{"post":{"slug":"how-to-set-up-a-database-2026","title":"How to set up a database in 2026: the practical guide","excerpt":"Choosing and setting up a database is the first real architecture decision in any new project. Here is the 2026-correct path without wasted effort.","category":"code","date":"April 3, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">E</span>very application eventually needs persistent storage, and the choice you make in week one shapes your architecture for years. In 2026, the decision surface is smaller than it looks: Postgres covers the vast majority of use cases, and the managed-service options make operational complexity nearly zero. Here is how to make the right call and set it up correctly.\n\n## What changed in 2026\n\n- **pgvector 0.7+ is production-grade** — storing and querying embeddings in Postgres is now a legitimate alternative to a dedicated vector database for most workloads.\n- **Neon branching is widely adopted** — database branches for PR previews, same pattern as Vercel branch deployments.\n- **Drizzle ORM overtook Prisma** in weekly downloads — its lightweight, SQL-close API and zero-runtime migration mode resonated with serverless teams.\n- **PlanetScale dropped its free tier** but its branching workflow influenced every major managed Postgres provider.\n- **SQLite on the server is real** — Turso (libSQL) and Cloudflare D1 make SQLite viable for edge-deployed apps.\n\n## Choosing your database\n\n| Use case | Best choice | Why |\n| --- | --- | --- |\n| General web app | Postgres | Best ecosystem, extensions, JSONB |\n| Edge-deployed app | SQLite (Turso / D1) | Low latency, no connection pool |\n| Caching / sessions | Redis (Upstash) | Sub-millisecond reads |\n| Time-series metrics | TimescaleDB | Postgres extension, hypertables |\n| Vector search | pgvector in Postgres | No second DB needed |\n| Document store | Postgres JSONB | Avoid MongoDB for new projects |\n\nThe \"just use Postgres\" answer is right ~80% of the time.\n\n## Managed service comparison\n\n| Service | Engine | Free tier | Branching | Edge-native |\n| --- | --- | --- | --- | --- |\n| Neon | Postgres 16 | Yes (generous) | Yes | Serverless driver |\n| Supabase | Postgres 16 | Yes | No | Partial |\n| PlanetScale | MySQL 8 | No | Yes | No |\n| Railway | Postgres / MySQL | Limited | No | No |\n| Turso | SQLite (libSQL) | Yes | Yes | Yes |\n\nFor a Next.js or SvelteKit app on Vercel, Neon is the most frictionless choice.\n\n## Setting up Postgres with Neon + Drizzle\n\n```bash\nnpm install drizzle-orm @neondatabase/serverless\nnpm install -D drizzle-kit\n```\n\n```ts\n// src/db/schema.ts\nimport { pgTable, serial, text, timestamp } from \"drizzle-orm/pg-core\";\n\nexport const tasks = pgTable(\"tasks\", {\n  id: serial(\"id\").primaryKey(),\n  title: text(\"title\").notNull(),\n  status: text(\"status\").notNull().default(\"todo\"),\n  createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n});\n```\n\n```ts\n// src/db/index.ts\nimport { neon } from \"@neondatabase/serverless\";\nimport { drizzle } from \"drizzle-orm/neon-http\";\nimport * as schema from \"./schema\";\n\nconst sql = neon(process.env.DATABASE_URL!);\nexport const db = drizzle(sql, { schema });\n```\n\n```json\n// drizzle.config.json\n{\n  \"schema\": \"./src/db/schema.ts\",\n  \"out\": \"./drizzle\",\n  \"dialect\": \"postgresql\",\n  \"dbCredentials\": { \"url\": \"$DATABASE_URL\" }\n}\n```\n\n```bash\nnpx drizzle-kit generate   # create migration SQL files\nnpx drizzle-kit migrate    # apply to database\n```\n\n## Connection pooling for serverless\n\nServerless functions (Vercel, Lambda) create a new database connection per invocation. Without pooling, you exhaust Postgres's connection limit (~100 for a small instance) almost immediately under load.\n\n**Solutions:**\n\n1. **Neon serverless driver** (`@neondatabase/serverless`) — uses HTTP instead of persistent TCP; no pooling needed.\n2. **PgBouncer** in transaction mode — sits between your app and Postgres, reusing connections.\n3. **Prisma Accelerate** — Prisma's managed connection pool and query cache.\n\n```ts\n// Neon HTTP driver — no pool exhaustion on serverless\nimport { neon } from \"@neondatabase/serverless\";\nconst sql = neon(process.env.DATABASE_URL!);\nconst rows = await sql`SELECT * FROM tasks WHERE status = ${\"todo\"}`;\n```\n\n## Migrations best practice\n\nNever `ALTER TABLE` in production manually. A migration workflow:\n\n1. **Edit** `schema.ts` — add or change a column.\n2. **Generate** — `drizzle-kit generate` creates a timestamped SQL file.\n3. **Review** — read the SQL; migrations that drop columns need a multi-step rollout.\n4. **Apply** — run in CI before deploying the new app version, not after.\n\nFor Prisma users, the equivalent is `prisma migrate dev` (development) and `prisma migrate deploy` (CI/CD).\n\n## How to pick your ORM\n\n| ORM | Style | Performance | TypeScript | Best for |\n| --- | --- | --- | --- | --- |\n| Drizzle | SQL-close | Excellent | Excellent | Serverless, SQL fans |\n| Prisma 6 | Abstracted | Good | Excellent | Rapid prototyping |\n| Kysely | Query builder | Excellent | Excellent | Type-safe raw SQL |\n| No ORM (postgres.js) | Raw SQL | Best | Manual | Simple scripts |\n\n## Common mistakes\n\n**Using connection strings with `sslmode=disable` in production.** Always use `sslmode=require` for cloud databases. A TLS-free connection is a security incident waiting to happen.\n\n**Running migrations inside the application on startup.** This creates race conditions in multi-instance deployments. Run migrations as a separate CI/CD step.\n\n**Storing large blobs in Postgres.** Files over ~1 MB should go to object storage (S3-compatible); Postgres `BYTEA` is not a CDN.\n\n**Not indexing foreign keys.** Postgres does not auto-index foreign key columns. An unindexed FK causes full table scans on every join.\n\n## What to skip\n\n- **MongoDB for new projects without a specific document-store use case** — Postgres JSONB handles most flexible-schema needs with better query tools.\n- **Self-hosted Postgres before you have a DBA** — backups, failover, and vacuuming require expertise; pay the managed service tax.\n- **ORM-generated migrations you do not review** — auto-generated `DROP COLUMN` migrations will ruin your day if applied to a busy production table.\n\n## FAQ\n\n**How do I back up my Neon/Supabase database?**\nManaged services handle backups automatically. For additional assurance, run `pg_dump` in a cron job and store the output in object storage.\n\n**Should I use UUIDs or serial IDs as primary keys?**\nUUIDs (`gen_random_uuid()`) are better for distributed systems and prevent enumeration. Serial integers are simpler and slightly faster for single-DB apps. `ULID` or `UUID v7` are good compromises in 2026 (sortable, globally unique).\n\n**Can I use Postgres for a queue?**\nYes — `SELECT ... FOR UPDATE SKIP LOCKED` implements a reliable queue. For high throughput (>1k jobs/sec), reach for a dedicated queue (BullMQ, Inngest).\n\n**Is SQLite worth considering for a new web app?**\nFor edge-deployed apps (Cloudflare Workers, Deno Deploy), SQLite via Turso or D1 is a serious choice. For a traditional server, Postgres is still the safer default.\n\n## Where to go next\n\n- [How to build a REST API in 2026](/blog/how-to-build-a-rest-api-2026)\n- [How to design a database schema in 2026](/blog/how-to-design-a-database-schema-2026)\n- [Postgres vs SQLite in 2026](/blog/postgres-vs-sqlite-2026)","hue":321,"metaTitle":"How to Set Up a Database in 2026: Postgres, ORMs, and Cloud","metaDescription":"Practical 2026 guide to setting up a database. Covers Postgres vs alternatives, managed services, migrations with Drizzle and Prisma, and connection pooling.","keywords":["how to set up a database 2026","postgres setup guide 2026","neon database tutorial","supabase setup 2026","drizzle orm tutorial 2026","prisma setup 2026","database migrations 2026","connection pooling serverless","postgres vs mysql 2026","managed database service 2026"],"tldr":["**Postgres is the safe default** for relational data in 2026 — pgvector, JSONB, and full-text search cover most use cases without adding a second database.","**Use a managed service from day one** — Neon, Supabase, or PlanetScale eliminate operational toil; self-hosted Postgres is rarely worth it before scale.","**Migrations are non-negotiable** — use Drizzle, Prisma, or Flyway; never hand-edit production schema.","**Connection pooling is mandatory** for serverless** — PgBouncer or Neon serverless driver prevent connection exhaustion on Lambda/Vercel.","**Skip:** starting with MongoDB \"for flexibility\" — schemaless does not mean schema-free; untyped documents create technical debt faster than a strict schema does."],"readTime":"5 min read","wordCount":1079},"related":[{"slug":"best-databases-for-startups-2026","title":"Best databases for startups in 2026: start boring, scale later","excerpt":"A practical guide to choosing a startup database in 2026 - why Postgres is the default, when to reach for something else, and the mistakes that cost you later.","category":"code","date":"May 14, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":195},{"slug":"rds-vs-aurora-2026","title":"RDS vs Aurora 2026: Which AWS Database Wins?","excerpt":"Managed off-the-shelf engine or Amazon cloud-native rebuild? A plain-language 2026 guide to cost, performance, failover, and when each one actually wins.","category":"code","date":"April 7, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":145},{"slug":"how-to-write-a-database-migration-2026","title":"How to write a database migration in 2026: safe, reversible, and zero-downtime","excerpt":"Database migrations fail when they lock tables in production or cannot be rolled back. This guide covers the 2026 patterns for safe, zero-downtime schema changes in Postgres.","category":"code","date":"April 6, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":305}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"how-to-use-ai-for-bug-triage-2026","title":"How to use AI for bug triage in 2026","excerpt":"AI can classify, prioritize, and suggest root causes for bug reports in seconds, but it needs good input data and human judgment on severity to avoid misprioritization.","category":"ai","date":"April 4, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":214},"older":{"slug":"how-to-set-up-a-home-server-2026","title":"How to set up a home server in 2026: hardware, OS, and first services","excerpt":"A home server gives you private cloud storage, media streaming, and automation without monthly fees. Here is how to build and configure one in 2026.","category":"tech","date":"April 3, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":228}}