<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/the-lifecycle-of-a-sharded-postgres-query-planetscale-ydgfxkyri" -->

---
title: The lifecycle of a sharded Postgres query — PlanetScale
description: An in-depth walkthrough traces a single SQL query&#x27;s journey through PlanetScale&#x27;s sharded Postgres system (codenamed Neki), covering authentication via...
canonical: https://daily.dev/posts/the-lifecycle-of-a-sharded-postgres-query-planetscale-ydgfxkyri
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: The lifecycle of a sharded Postgres query — PlanetScale | daily.dev
og:description: An in-depth walkthrough traces a single SQL query&#x27;s journey through PlanetScale&#x27;s sharded Postgres system (codenamed Neki), covering authentication via...
og:url: https://daily.dev/posts/the-lifecycle-of-a-sharded-postgres-query-planetscale-ydgfxkyri
og:image: https://api.daily.dev/og/posts/YdGfxkYRi.png
og:image:alt: The lifecycle of a sharded Postgres query — PlanetScale
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# The lifecycle of a sharded Postgres query — PlanetScale

**[PlanetScale](https://daily.dev/sources/planetscale)** · 22 min read · 1 upvotes · 0 comments

## Summary

An in-depth walkthrough traces a single SQL query's journey through PlanetScale's sharded Postgres system (codenamed Neki), covering authentication via SCRAM-SHA-256, the Postgres wire protocol's Simple vs Extended modes, a custom Go-based SQL parser (~18,000 lines), and a distributed query planner that must decide how to join tables spread across shards. It explains nested-loop vs hash join strategies, how the router builds and probes hash tables in memory (or spills to disk), how sidecars manage pooled Postgres connections per shard, and how an evaluation engine recombines partial aggregates like averages across shards. The piece closes by showing that choosing a better shard key (sharding orders by customer_id instead of orders.id) lets Postgres perform joins locally, cutting shard requests in half and eliminating router-side joins entirely.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://planetscale.com/blog/the-lifecycle-of-a-sharded-postgres-query>

## Questions this post answers

### What's the difference between the Simple and Extended query protocols in Postgres?

The Simple protocol sends an entire SQL statement, including literal values, in one Query message and can accept multiple statements at once, making it suited for ad hoc use like psql. The Extended protocol splits execution into five steps: Parse, Bind, Describe, Execute, and Sync, giving drivers separate control over preparing a statement, binding parameters, and executing it, which lets a prepared statement be reused without re-parsing.

_daily.dev surfaces deep dives like this for engineers debugging driver-level Postgres protocol behavior._

### How does a distributed SQL router decide between a nested-loop join and a hash join across database shards?

The choice depends on estimated table sizes and shard request costs. With roughly 100,000 customers and 300,000 qualifying orders across four shards, a nested-loop join would require a scatter-gather query per customer, resulting in thousands of shard requests, while a hash join fetches each table with just four shard queries per side, building an in-memory hash table on the smaller input to minimize memory and network cost.

_engineers weighing join strategies for sharded systems can track this kind of architectural reasoning on daily.dev._

### Why does sharding orders by customer_id instead of orders.id improve join performance in a sharded Postgres database?

Sharding orders by customer_id colocates each customer's orders on the same shard as that customer, letting Postgres perform the join locally on a single node instead of requiring the router to fetch customers and orders separately and join them in memory. This cuts the number of shard requests from eight down to four and removes the need to build a router-side hash table entirely.

_daily.dev helps engineers comparing shard key strategies keep up with practical database design tradeoffs._

## Similar posts on daily.dev

- [Making 768 servers look like 1 — PlanetScale](https://daily.dev/posts/making-768-servers-look-like-1-planetscale-2dvlb3eoz) · Hacker News · 0 upvotes · 0 comments

---

Tags: [#postgresql](https://daily.dev/tags/postgresql), [#distributed-systems](https://daily.dev/tags/distributed-systems), [#planetscale](https://daily.dev/tags/planetscale)

[View this post on daily.dev](https://daily.dev/posts/the-lifecycle-of-a-sharded-postgres-query-planetscale-ydgfxkyri)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"The lifecycle of a sharded Postgres query — PlanetScale","url":"https://daily.dev/posts/the-lifecycle-of-a-sharded-postgres-query-planetscale-ydgfxkyri","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/the-lifecycle-of-a-sharded-postgres-query-planetscale-ydgfxkyri"},"datePublished":"2026-09-10T14:53:19.271Z","dateModified":"2026-09-10T15:15:06.456Z","description":"An in-depth walkthrough traces a single SQL query's journey through PlanetScale's sharded Postgres system (codenamed Neki), covering authentication via...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/a7bdc08d885a71e3abd9e35fc4725944?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/a7bdc08d885a71e3abd9e35fc4725944?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"PlanetScale","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"PlanetScale","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/09515c29cafc45618b3f117eab4fccf8","url":"https://daily.dev/squads/planetscale"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/the-lifecycle-of-a-sharded-postgres-query-planetscale-ydgfxkyri","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"postgresql,distributed-systems,planetscale","timeRequired":"PT22M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"PlanetScale","item":"https://daily.dev/squads/planetscale"},{"@type":"ListItem","position":3,"name":"The lifecycle of a sharded Postgres query — PlanetScale"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/the-lifecycle-of-a-sharded-postgres-query-planetscale-ydgfxkyri#faq","mainEntity":[{"@type":"Question","name":"What's the difference between the Simple and Extended query protocols in Postgres?","acceptedAnswer":{"@type":"Answer","text":"The Simple protocol sends an entire SQL statement, including literal values, in one Query message and can accept multiple statements at once, making it suited for ad hoc use like psql. The Extended protocol splits execution into five steps: Parse, Bind, Describe, Execute, and Sync, giving drivers separate control over preparing a statement, binding parameters, and executing it, which lets a prepared statement be reused without re-parsing. daily.dev surfaces deep dives like this for engineers debugging driver-level Postgres protocol behavior."}},{"@type":"Question","name":"How does a distributed SQL router decide between a nested-loop join and a hash join across database shards?","acceptedAnswer":{"@type":"Answer","text":"The choice depends on estimated table sizes and shard request costs. With roughly 100,000 customers and 300,000 qualifying orders across four shards, a nested-loop join would require a scatter-gather query per customer, resulting in thousands of shard requests, while a hash join fetches each table with just four shard queries per side, building an in-memory hash table on the smaller input to minimize memory and network cost. engineers weighing join strategies for sharded systems can track this kind of architectural reasoning on daily.dev."}},{"@type":"Question","name":"Why does sharding orders by customer_id instead of orders.id improve join performance in a sharded Postgres database?","acceptedAnswer":{"@type":"Answer","text":"Sharding orders by customer_id colocates each customer's orders on the same shard as that customer, letting Postgres perform the join locally on a single node instead of requiring the router to fetch customers and orders separately and join them in memory. This cuts the number of shard requests from eight down to four and removes the need to build a router-side hash table entirely. daily.dev helps engineers comparing shard key strategies keep up with practical database design tradeoffs."}}]}
```

