# Async CSV reads keep every row

> Agno's CSVReader.async_read() with RowChunking(skip_header=True) now keeps the first data row of every page after the first, so async and sync reads return the same rows.

- Published: 2026-09-16
- Author: Kyubum Hwang
- Categories: Changelog
- Canonical: https://www.agno.com/articles/async-csv-reads-keep-every-row
- Markdown: https://www.agno.com/articles/async-csv-reads-keep-every-row.md

Agno's `CSVReader.async_read()` splits large files into pages of 1,000 rows, and with `RowChunking(skip_header=True)` it now skips only the file's first row. The reader used to treat the first row of each page as a header and skip it, so every page after the first lost a data row. A file with 1,002 records returned 1,002 rows from `read()` and 1,001 from `async_read()`.

```python
from agno.knowledge.chunking.row import RowChunking
from agno.knowledge.reader.csv_reader import CSVReader

reader = CSVReader(chunking_strategy=RowChunking(skip_header=True))
documents = await reader.async_read("orders.csv")
```

![A header and 12 data rows read in pages of 3 rows. Before, rows 3, 6, 9 and 12 were dropped, leaving 8 of 12. Now all 12 rows are kept.](https://www.agno.com/images/v3-0-10-csv-rows.png)

Row numbers now stay continuous across pages. Files small enough to read as one document weren't affected.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/07_knowledge/09_archive/readers/csv_reader_async.py), and learn more about [CSV row chunking](https://docs.agno.com/knowledge/concepts/chunking/csv-row-chunking) and the [CSV reader](https://docs.agno.com/knowledge/concepts/readers/csv-reader) in the documentation.
