[{"data":1,"prerenderedAt":244},["ShallowReactive",2],{"nav-stories":3,"footer-stories":61,"blog-serverless-data-architecture":74},[4,16,25,34,43,52],{"id":5,"color":6,"extension":7,"image":8,"label":9,"link":10,"meta":11,"order":12,"stem":13,"text":14,"__hash__":15},"stories\u002Fstories\u002F01-data-center.yml",null,"yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1558494949-ef010cbdcc31?w=1080","DATA_CENTER","https:\u002F\u002Fx.com\u002Fabbeytetteh_",{},1,"stories\u002F01-data-center","Racking new servers. 40gbit backbone online.","0QUZQbaANhdO8WemZxkDdO7vbVopfnynHtH9FxBZb_w",{"id":17,"color":6,"extension":7,"image":18,"label":19,"link":6,"meta":20,"order":21,"stem":22,"text":23,"__hash__":24},"stories\u002Fstories\u002F02-thoughts.yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1498050108023-c5249f4df085?w=1080","THOUGHTS",{},2,"stories\u002F02-thoughts","Late night bug hunting. Found the memory leak.","Gd1am954aasY6HRHD7hCtOuessXb6zYZ8iizS501ICg",{"id":26,"color":27,"extension":7,"image":6,"label":28,"link":6,"meta":29,"order":30,"stem":31,"text":32,"__hash__":33},"stories\u002Fstories\u002F03-coding.yml","#3b82f6","CODING",{},3,"stories\u002F03-coding","Just thinking about how much easier life is with Swarm.","vLAyiGUPtlXB2SHa5KM_U2AaK4QkG3Og85UEUE7qzgM",{"id":35,"color":6,"extension":7,"image":36,"label":37,"link":6,"meta":38,"order":39,"stem":40,"text":41,"__hash__":42},"stories\u002Fstories\u002F04-update.yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1591799264318-7e6ef8ddb7ea?w=1080","UPDATE",{},4,"stories\u002F04-update","New cluster nodes arrived. Prepping for installation.","kyT60N5C6Re_jMonZbgNy0PbQhzXmUWxDbD0D_v43ts",{"id":44,"color":45,"extension":7,"image":6,"label":46,"link":6,"meta":47,"order":48,"stem":49,"text":50,"__hash__":51},"stories\u002Fstories\u002F05-setup.yml","#86868b","SETUP",{},5,"stories\u002F05-setup","Optimizing the telemetry pipeline for 1M req\u002Fs.","cPOBkzoyXsCmPgRO2d80Hj3vm4MP-6nAejtlQ5iuSzw",{"id":53,"color":6,"extension":7,"image":54,"label":55,"link":6,"meta":56,"order":57,"stem":58,"text":59,"__hash__":60},"stories\u002Fstories\u002F06-travel.yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1560969184-10fe8719e047?w=1080","TRAVEL",{},6,"stories\u002F06-travel","Travel log — system architecture workshop in Berlin.","jnOxerdF6usAIHdR35Z-opx0LJAy9kZluXnZhtz62Z0",[62,64,66,68,70,72],{"id":5,"color":6,"extension":7,"image":8,"label":9,"link":10,"meta":63,"order":12,"stem":13,"text":14,"__hash__":15},{},{"id":17,"color":6,"extension":7,"image":18,"label":19,"link":6,"meta":65,"order":21,"stem":22,"text":23,"__hash__":24},{},{"id":26,"color":27,"extension":7,"image":6,"label":28,"link":6,"meta":67,"order":30,"stem":31,"text":32,"__hash__":33},{},{"id":35,"color":6,"extension":7,"image":36,"label":37,"link":6,"meta":69,"order":39,"stem":40,"text":41,"__hash__":42},{},{"id":44,"color":45,"extension":7,"image":6,"label":46,"link":6,"meta":71,"order":48,"stem":49,"text":50,"__hash__":51},{},{"id":53,"color":6,"extension":7,"image":54,"label":55,"link":6,"meta":73,"order":57,"stem":58,"text":59,"__hash__":60},{},{"id":75,"title":76,"body":77,"date":229,"description":230,"extension":231,"meta":232,"navigation":170,"path":233,"readTime":234,"seo":235,"stem":236,"tags":237,"thumbnail":242,"__hash__":243},"blog\u002Fblog\u002Fserverless-data-architecture.md","The Transition to Serverless Data Architecture",{"type":78,"value":79,"toc":223},"minimark",[80,84,89,92,100,104,107,123,126,130,133,206,209,213,216,219],[81,82,83],"p",{},"I ran a self-hosted Postgres cluster on OpenStack for two years. Then I moved the same workload to a managed service. This post is an honest accounting of what changed — the good and the bad.",[85,86,88],"h2",{"id":87},"what-you-give-up-running-it-yourself","What You Give Up Running It Yourself",[81,90,91],{},"Self-hosting gives you control, but control is a liability masquerading as an asset. Every tuning decision, every WAL configuration, every failover test is time you're not spending on the product. Our DBA runbook was 40 pages long and only one person had actually read all of it.",[81,93,94,95,99],{},"The cost of expertise compounds. When the primary went down at 2am on a Saturday, someone had to know what ",[96,97,98],"code",{},"pg_ctl promote"," does and when to run it.",[85,101,103],{"id":102},"what-you-actually-get-from-managed-services","What You Actually Get from Managed Services",[81,105,106],{},"Neon gave us:",[108,109,110,114,117,120],"ul",{},[111,112,113],"li",{},"Branching — spin up a full copy of the database for a PR in under 30 seconds",[111,115,116],{},"Automatic point-in-time recovery with a simple API call",[111,118,119],{},"Scale-to-zero during off-hours (real savings on non-critical environments)",[111,121,122],{},"Connection pooling via PgBouncer baked in",[81,124,125],{},"The branching feature alone changed how we do development. Before, dev environments shared a staging database because spinning up a fresh Postgres with a full dataset was too slow. Now it's a single CLI command.",[85,127,129],{"id":128},"the-migration","The Migration",[81,131,132],{},"We ran both systems in parallel for three weeks using logical replication:",[134,135,140],"pre",{"className":136,"code":137,"language":138,"meta":139,"style":139},"language-sql shiki shiki-themes vitesse-light","-- On the source (self-hosted)\nCREATE PUBLICATION migration_pub FOR ALL TABLES;\n\n-- On the target (Neon)\nCREATE SUBSCRIPTION migration_sub\n  CONNECTION 'host=old-primary ...'\n  PUBLICATION migration_pub;\n","sql","",[96,141,142,150,166,172,177,184,200],{"__ignoreMap":139},[143,144,146],"span",{"class":145,"line":12},"line",[143,147,149],{"class":148},"s8zF2","-- On the source (self-hosted)\n",[143,151,152,156,160,163],{"class":145,"line":21},[143,153,155],{"class":154},"sbBg2","CREATE",[143,157,159],{"class":158},"suHK_"," PUBLICATION migration_pub ",[143,161,162],{"class":154},"FOR",[143,164,165],{"class":158}," ALL TABLES;\n",[143,167,168],{"class":145,"line":30},[143,169,171],{"emptyLinePlaceholder":170},true,"\n",[143,173,174],{"class":145,"line":39},[143,175,176],{"class":148},"-- On the target (Neon)\n",[143,178,179,181],{"class":145,"line":48},[143,180,155],{"class":154},[143,182,183],{"class":158}," SUBSCRIPTION migration_sub\n",[143,185,186,189,193,197],{"class":145,"line":57},[143,187,188],{"class":154},"  CONNECTION",[143,190,192],{"class":191},"sSP4y"," '",[143,194,196],{"class":195},"spphp","host=old-primary ...",[143,198,199],{"class":191},"'\n",[143,201,203],{"class":145,"line":202},7,[143,204,205],{"class":158},"  PUBLICATION migration_pub;\n",[81,207,208],{},"Logical replication gave us a live feed of changes. The final cutover was a matter of updating the connection string in the Nuxt runtime config and flipping DNS — 4 seconds of write downtime, confirmed by our uptime monitor.",[85,210,212],{"id":211},"where-self-hosting-still-wins","Where Self-Hosting Still Wins",[81,214,215],{},"If you have regulatory requirements that prohibit data leaving a specific jurisdiction, managed services often can't help. Likewise, if your data access patterns are unusual enough that you need to tune kernel parameters or run custom Postgres extensions not available in managed offerings, self-hosting remains necessary.",[81,217,218],{},"But for most product workloads? The managed path recovers 6–10 hours of engineering time per month and eliminates a class of 2am incidents entirely. That's the real calculation.",[220,221,222],"style",{},"html pre.shiki code .s8zF2, html code.shiki .s8zF2{--shiki-default:#A0ADA0}html pre.shiki code .sbBg2, html code.shiki .sbBg2{--shiki-default:#1E754F}html pre.shiki code .suHK_, html code.shiki .suHK_{--shiki-default:#393A34}html pre.shiki code .sSP4y, html code.shiki .sSP4y{--shiki-default:#B5695977}html pre.shiki code .spphp, html code.shiki .spphp{--shiki-default:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":139,"searchDepth":21,"depth":21,"links":224},[225,226,227,228],{"id":87,"depth":21,"text":88},{"id":102,"depth":21,"text":103},{"id":128,"depth":21,"text":129},{"id":211,"depth":21,"text":212},"2026-03-10","Evaluating the real trade-offs between managed database services and self-hosted high-availability clusters — after running both in production.","md",{},"\u002Fblog\u002Fserverless-data-architecture","6 min",{"title":76,"description":230},"blog\u002Fserverless-data-architecture",[238,239,240,241],"Database","Infrastructure","PostgreSQL","Architecture","\u002Fimages\u002Fthumbnails\u002Fserverless-data-architecture.png","5puaNbRfvwcsew1zr4NPBWVcp6vptf8ytTvNFyvu5x0",1779361989416]