electric-sql / electric-sql/electric
Fetch/Request subset snapshot returns data twice
- Dominant language
- TypeScript
- Stars
- 10.4k
- Forks
- 375
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 18
Description
**Versions**
- Client: "@electric-sql/client": "^1.5.15",
- Electric: 1.5.1
**Bug description**
I'm using `fetchSnapshot()`.
I see that 2 network requests are made returning the same data but different `"snapshot_mark": 1981649824"`.
When minimising it towards only the example from [the docs](https://electric-sql.com/docs/guides/shapes#requesting-subset-snapshots). It also happens:
```ts
const stream = new ShapeStream({
url: 'http://localhost:3000/v1/shape',
params: { table: 'items' },
log: 'changes_only',
})
// Load high-priority items with pagination
const { metadata, data } = await stream.requestSnapshot({
where: "priority = $1",
params: { '1': 'high' },
orderBy: 'created_at DESC',
limit: 20,
offset: 0,
})
```
Note that i'm using `fetchSnapshot()` and not `requestSnapshot()`.
**Expected behavior**
I'm expecting only 1 network request with the data.
**Vid**
https://github.com/user-attachments/assets/367af5dc-4d61-40e6-bad1-a2c5df800e37
**Extra context**
```md
This isn’t your app doing two separate fetchSnapshot calls for the same page — it’s how the @electric-sql/client HTTP stack works for chunked shape responses.
What’s going on
1. First request (offset=now, no handle in the URL)
This is the initial request for that snapshot. The server answers with:
• the first chunk of the snapshot body, and
• response headers such as electric-handle and electric-offset (see SHAPE_HANDLE_HEADER / CHUNK_LAST_OFFSET_HEADER in the client).
2. Second request (same path, but now handle=… and offset=191558552_0)
The client builds a continuation URL from those headers and issues another GET. That comes from createFetchWithChunkBuffer + getNextChunkUrl in node_modules/@electric-sql/client/dist/index.mjs:
after a response, if there is a handle and last-offset and the snapshot is not marked up-to-date, it sets handle + offset on the URL for the next chunk and can prefetch it (the prefetch queue defaults
allow multiple chunk prefetches).
So you see two HTTP round-trips for one logical fetchSnapshot: first chunk + next chunk (often prefetched before you “need” it).
```
Contributor guide
Assessment
This issue has not been assessed yet.