Commit 6442be6
fix: Properly fix memory leak in query result handling (v25.11.2)
The initial v25.11.2 fix was ineffective because it deleted the result
dict but the data was still referenced by the response object returned
to FastAPI. Memory would only be freed after JSON serialization and
network transmission completed.
Root cause analysis:
1. DuckDB fetchall() returns result in DuckDB memory
2. List comprehension copies data to Python lists
3. Data copied into response_data object
4. del result only deleted dict wrapper, not the data
5. GC ran but had nothing to collect (data still referenced)
6. Data stayed in memory through FastAPI serialization
Fixes in this release:
**api/duckdb_engine.py**:
- Delete rows reference immediately after conversion to free DuckDB memory
- Reduces memory footprint during query execution
**api/main.py**:
- More aggressive GC: every 50 queries (was 100) or 30s (was 60s)
- Better logging: show collected object count and reason
- GC runs before returning to maximize cleanup window
**api/duckdb_pool_simple.py**:
- Run GC after every query in connection cleanup
- Log significant collections (>100 objects) for monitoring
- Ensures DuckDB internal state is cleaned up
This three-layer approach ensures memory is freed at:
1. DuckDB result level (engine)
2. Python object level (main.py GC)
3. Connection pool level (pool cleanup)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>1 parent 34e92b6 commit 6442be6
3 files changed
Lines changed: 52 additions & 23 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
377 | 377 | | |
378 | 378 | | |
379 | 379 | | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
380 | 387 | | |
381 | 388 | | |
382 | 389 | | |
383 | 390 | | |
384 | | - | |
| 391 | + | |
385 | 392 | | |
386 | | - | |
| 393 | + | |
387 | 394 | | |
388 | 395 | | |
389 | 396 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
146 | 146 | | |
147 | 147 | | |
148 | 148 | | |
149 | | - | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
150 | 152 | | |
151 | | - | |
152 | | - | |
153 | | - | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
154 | 160 | | |
155 | 161 | | |
156 | 162 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1254 | 1254 | | |
1255 | 1255 | | |
1256 | 1256 | | |
1257 | | - | |
| 1257 | + | |
1258 | 1258 | | |
1259 | 1259 | | |
1260 | 1260 | | |
1261 | 1261 | | |
1262 | | - | |
| 1262 | + | |
1263 | 1263 | | |
1264 | 1264 | | |
1265 | | - | |
| 1265 | + | |
1266 | 1266 | | |
1267 | 1267 | | |
1268 | | - | |
1269 | | - | |
1270 | | - | |
| 1268 | + | |
| 1269 | + | |
| 1270 | + | |
1271 | 1271 | | |
| 1272 | + | |
1272 | 1273 | | |
1273 | | - | |
1274 | | - | |
1275 | | - | |
1276 | | - | |
1277 | | - | |
1278 | | - | |
1279 | | - | |
| 1274 | + | |
| 1275 | + | |
| 1276 | + | |
1280 | 1277 | | |
1281 | 1278 | | |
| 1279 | + | |
| 1280 | + | |
| 1281 | + | |
| 1282 | + | |
| 1283 | + | |
| 1284 | + | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
1282 | 1288 | | |
1283 | | - | |
| 1289 | + | |
1284 | 1290 | | |
1285 | 1291 | | |
1286 | 1292 | | |
1287 | 1293 | | |
1288 | | - | |
1289 | | - | |
1290 | | - | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
1291 | 1297 | | |
1292 | 1298 | | |
| 1299 | + | |
| 1300 | + | |
| 1301 | + | |
| 1302 | + | |
| 1303 | + | |
| 1304 | + | |
| 1305 | + | |
| 1306 | + | |
| 1307 | + | |
| 1308 | + | |
1293 | 1309 | | |
1294 | 1310 | | |
1295 | 1311 | | |
| |||
0 commit comments