Уявіть: ваш інтернет-магазин на RDS починає гальмувати в піки, а ви переплачуєте за простоюючі ресурси. Serverless бази даних вирішують цю проблему — вони автоматично масштабуються до нуля при простої та тарифікуються за споживанням. Але неправильне проектування схеми зведе економію нанівець: наприклад, часті сканування в DynamoDB можуть обійтися дорожче фіксованої інфраструктури. Ми налаштовуємо serverless БД для високонавантажених проєктів: DynamoDB, PlanetScale і Neon. З 5+ роками досвіду в serverless архітектурах ми впровадили рішення для 50+ проєктів — від e-commerce до IoT.
Згідно з документацією AWS, коректне застосування Single-Table Design знижує кількість операцій читання до 90%.
Чому варто обрати serverless базу даних?
Serverless БД усувають необхідність управління інфраструктурою. Ви не платите за простоюючі ресурси, а масштабування відбувається автоматично. Для проєктів з нерівномірним навантаженням це знижує вартість інфраструктури на 35–40%. Однак неправильне проектування схеми може звести нанівець всі переваги: наприклад, часті сканування в DynamoDB призведуть до високих витрат.
Як вибрати між DynamoDB та PostgreSQL?
Вибір залежить від вашої моделі даних. Якщо вам потрібні складні агрегації, JOIN та транзакції — обирайте Neon (PostgreSQL). Якщо ви маєте справу з високими навантаженнями та простими запитами — DynamoDB з Single-Table Design забезпечить затримку в 5 разів нижчу, ніж MySQL при 1000+ запитів/с.
Чи підходить Serverless для вашого бізнесу?
Serverless архітектура ідеальна для проєктів з нерівномірним навантаженням, де важлива економія ресурсів. Наприклад, для SaaS-продукту з 10 000 користувачів вартість DynamoDB On-Demand складає близько $50/міс., що в 3 рази дешевше за виділений RDS.
Порівняння варіантів
| БД | Тип | Масштаб | Найкращий сценарій |
|---|---|---|---|
| DynamoDB | Key-value / Document | Безлімітний | Високе навантаження, передбачувані запити |
| PlanetScale | MySQL-compatible | До терабайт | Реляційні дані, GitHub-style branching |
| Neon | PostgreSQL | Малий-середній | Повний SQL, dev environments |
| FaunaDB | Document / Relational | Середній | Мультирегіональна узгодженість |
| Upstash | Redis | Малий-середній | Кеш, черги, rate limiting |
DynamoDB: проектування під serverless
DynamoDB вимагає думати про доступ до даних до проектування схеми. Погано спроектована таблиця — дорога і повільна. Єдиний правильний підхід — Single-Table Design, коли весь домен зберігається в одній таблиці, а PK/SK кодують тип сутності:
# Схема для e-commerce # PK | SK | Дані # USER#u123 | PROFILE | {name, email} # USER#u123 | ORDER#o456 | {status, total, items} # USER#u123 | ORDER#o789 | {status, total, items} # ORDER#o456 | ITEM#i001 | {product_id, qty, price} # PRODUCT#p001 | METADATA | {title, description} import boto3 from boto3.dynamodb.conditions import Key dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('ecommerce') def get_user_with_orders(user_id: str) -> dict: response = table.query( KeyConditionExpression=Key('PK').eq(f'USER#{user_id}') & Key('SK').begins_with('ORDER#') ) return response['Items'] def put_order(user_id: str, order: dict): with table.batch_writer() as batch: batch.put_item(Item={ 'PK': f'USER#{user_id}', 'SK': f'ORDER#{order["id"]}', **order }) batch.put_item(Item={ 'PK': f'ORDER#{order["id"]}', 'SK': 'METADATA', 'GSI1PK': f'STATUS#{order["status"]}', 'GSI1SK': order['created_at'], **order }) Global Secondary Index (GSI) — для альтернативних патернів доступу, наприклад, отримати всі замовлення за статусом.
DynamoDB On-Demand vs Provisioned
On-Demand: платиш за кожен read/write. Немає планування потужності. Ідеально для unpredictable трафіку або нових застосунків.
Provisioned + Auto Scaling: задаєш baseline RCU/WCU, автомасштабування при піках. Дешевше при передбачуваному навантаженні.
resource "aws_dynamodb_table" "ecommerce" { name = "ecommerce" billing_mode = "PAY_PER_REQUEST" # On-demand hash_key = "PK" range_key = "SK" attribute { name = "PK" type = "S" } attribute { name = "SK" type = "S" } attribute { name = "GSI1PK" type = "S" } attribute { name = "GSI1SK" type = "S" } global_secondary_index { name = "GSI1" hash_key = "GSI1PK" range_key = "GSI1SK" projection_type = "ALL" } ttl { attribute_name = "expires_at" enabled = true } } Neon: Serverless PostgreSQL
Neon розділяє compute і storage. Compute масштабується до нуля при відсутності активності, storage оплачується за обсягом. Вбудований branching дозволяє створювати ізольовані середовища за секунди.
import psycopg2 import os conn = psycopg2.connect(os.environ['DATABASE_URL']) with conn.cursor() as cur: cur.execute("SELECT * FROM orders WHERE user_id = %s", (user_id,)) orders = cur.fetchall() Branching в Neon:
neon branches create --name feature/new-schema --parent main neon connection-string feature/new-schema # → postgresql://user:[email protected]/neondb PlanetScale
MySQL-сумісний сервіс з branching workflow, без foreign key constraints (vitess-based). Використовує HTTP-протокол, що особливо добре для Lambda:
import { connect } from '@planetscale/database' const conn = connect({ host: process.env.DATABASE_HOST, username: process.env.DATABASE_USERNAME, password: process.env.DATABASE_PASSWORD }) const results = await conn.execute( 'SELECT * FROM orders WHERE user_id = ?', [userId] ) Як налаштувати connection pooling для Lambda: покрокова інструкція
- Визначте тип БД: для RDS використовуйте RDS Proxy, для Neon — вбудований pooler, для PlanetScale — HTTP-протокол вже вирішує проблему.
- Для PostgreSQL з PgBouncer: розгорніть PgBouncer поруч з Lambda (наприклад, у VPC), налаштуйте pool_mode = transaction.
- При використанні Prisma: замініть прямі підключення на Prisma Accelerate через змінну середовища
DATABASE_URL. - Перевірте кількість одночасних з'єднань: для 100 Lambda-функцій знадобиться близько 20 з'єднань у пулі.
- Протестуйте cold start: перший запит після простою не повинен перевищувати 300 мс.
Connection pooling для Lambda
Lambda створює нове з'єднання при кожному cold start. При 100 concurrent Lambda — 100 з'єднань. Це вбиває PostgreSQL/MySQL. Рішення:
| Рішення | Опис | Найкраще для |
|---|---|---|
| RDS Proxy (AWS) | Connection pooler перед RDS, прозорий | Застосунків на RDS |
| PgBouncer | Self-hosted, перед PostgreSQL | Будь-який PostgreSQL, тонкий тюнінг |
| Neon/PlanetScale | Вбудований pooling | Managed сервіси, Zero config |
| Prisma Accelerate | Pooler + query cache | Stack на Prisma |
Кейс: міграція замовника з RDS на Neon
Проєкт: інтернет-магазин з сезонними піками (Чорна п'ятниця). База даних — PostgreSQL 13 на RDS. Середнє навантаження — 2000 запитів/с, у піку — 15 000. RDS не справлявся, доводилося тримати надлишкові потужності.
Рішення: міграція на Neon з PostgreSQL 15. Підсумки:
- Вартість інфраструктури знизилася на 35% (з 450 000 до 290 000 ₴/міс).
- Cold start (після перерви) — 200 мс проти колишніх 2 с на RDS (в 10 разів швидше).
- Час індексації нових даних скоротився втричі завдяки паралельним операціям.
- Команда отримала можливість створювати гілки для кожного PR, що прискорило розробку.
Що входить у роботу
- Проектування схеми (Single-Table Design для DynamoDB, нормалізація для Neon/PlanetScale).
- Налаштування connection pooling (RDS Proxy, PgBouncer, вбудований).
- Оптимізація запитів (індекси, GSIs, бенчмарки).
- CI/CD для branching (автоматичне створення гілок при пулл-реквестах).
- Документація схеми та інструкції для команди.
- Навчання розробників (ваші інженери зможуть самостійно вносити зміни).
- Гарантія підтримки протягом 30 днів після здачі.
Орієнтовні терміни
- DynamoDB single-table design + базові операції — 3-5 днів.
- Neon / PlanetScale підключення + pooling — 1-2 дні.
- Міграція існуючої БД на serverless — 5-14 днів.
Терміни варіюються залежно від складності схеми та обсягу даних. Отримайте консультацію щодо вашого проєкту — зв'яжіться з нами для оцінки. Ми підберемо оптимальне рішення та запропонуємо план робіт.
Детальний приклад розрахунку вартості
Для проєкту з 10 000 активних користувачів і 100 000 запитів/день вартість DynamoDB On-Demand становить близько $50/міс., що в 3 рази дешевше за виділений RDS з аналогічною продуктивністю.







