Your contract events,
in your own Postgres.
Give it an event spec and a contract ID. Sorolog streams every Soroban event into your own PostgreSQL — one table per event, reliable and gap-free — from a single YAML manifest. Point it at any stellar-rpc, or run your own captive core in-pod and read straight from the validators — chain to SQL as low as 244ms.
Hosted indexers are delayed, rate-limited, and keep your data on their side. Raw stellar-rpc leaves paging, the retention window and XDR decoding to you. SubQuery means projects and heavy ops. There was no declarative path to your events, in your Postgres, in plain SQL.
Declare it. The operator does the rest.
One Indexer resource describes what you want. A Kubernetes operator keeps it true — schema, tables, worker, status.
Write one manifest
Contracts, event-spec ref, source (rpc or your own core), storage — the whole setup.
kind: Indexer metadata: { name: usdc-stellar } spec: rpc: # health-checked failover - https://soroban-testnet.stellar.org contracts: - contractId: "CBIEL…DAMA" eventSpec: { configMapRef: usdc-events } startLedger: 0
The operator provisions
A reconcile loop turns the spec into running parts — and heals them.
Query plain SQL
Each event is a table in your Postgres. No API between you and your data.
-- one table per event SELECT "from", "to", amount FROM usdc_transfer WHERE amount > 1000000000 ORDER BY ledger DESC;
event spec in → tables out · empty events list = every event in the spec · startLedger: 0 backfills from the RPC retention window
Bring an RPC, or be the source.
One field decides where your events come from. Start on any stellar-rpc; run your own captive core when latency matters. Same schema, same rows either way — source: rpc | core.
Point at any stellar-rpc
A public endpoint or your own. Sorolog polls it with phase-locked, gap-free ingestion — no paging, retention, or XDR decoding left on you. Nothing extra to run.
- infra
- none beyond the worker
- latency
- as low as 747ms
- nodes
- any architecture
Best for most indexers. Start here.
Run your own node, in-pod
Sorolog runs captive stellar-core inside the worker and reads events straight from the validators — no RPC and no provider queue anywhere in the path.
- infra
- captive core · amd64 node
- latency
- as low as 244ms
- reads
- straight from the validators
When every millisecond counts.
Both modes write byte-identical rows into your Postgres — same tables, same event ids — so you can switch a running indexer by changing one field. Deleting the CR cleans up the worker; your data stays.
Even if the network blips, no data is lost.
A poll-based backbone chosen for loss-free, self-healing ingestion — not just latency. Don't take our word for it: break something.
The last processed ledger lives in Postgres. After any crash it resumes exactly there.
Event inserts and cursor advance share one transaction — a commit, or nothing.
Ledgers are final the moment they close — what Sorolog writes never gets rolled back.
A passphrase-checked pool with rotation and backoff. A blip never becomes a gap.
Measured, not promised.
Every number comes from running the real worker against the public Stellar testnet and reading only its production surface — Postgres rows and /metrics. Two ingestion modes, same data: point it at any stellar-rpc, or run your own captive core in-pod and read straight from the validators.
Own node, straight from the overlay — and that's under x86 emulation; native hardware is faster still. Full distribution in docs/benchmarks/.
Public RPC (gateway.fm + SDF), bounded below by the provider's ~0.87s visibility floor — which source: core deletes entirely.
Burst-ingest ceiling (multi-row transactional writes); backfill catches 50,000 real ledgers at 2,626 ledgers/s.
Measured on the same live ledgers into the same Postgres, source: core delivered every ledger a median 579ms sooner than the public-RPC path and never slower — while producing byte-identical rows (277/277 shared events matched). rpc mode needs zero extra infra and stays the default; core deletes the provider floor for the lowest latency. Methodology and raw results live in docs/benchmarks/.
A specific combination nobody else offers.
| Mercury | SubQuery | Raw RPC | Sorolog | |
|---|---|---|---|---|
| Data in your own DB | No | Via subquery-node | If you build it | ✓ Yes |
| Plain SQL access | GraphQL | GraphQL | Raw XDR/JSON | ✓ Yes |
| Retention & gap handling | Theirs | Yes | On you | ✓ Built-in |
| Setup effort | Low | Med–high | High | ✓ One YAML |
| Measured latency | Not published | Not published | — | ✓ as low as 244ms own node · 747ms public |
Honest positioning: Mercury stays great for hosted zero-ops indexing; SubQuery for multi-chain projects. Sorolog is for teams that want their own Postgres, plain SQL, and K8s-native ops — together.
One YAML. A running indexer.
Runs in your cluster. Your data never leaves it.
$ kubectl apply -f https://sorolog.com/install.yaml