![](https://blog.atj.sh/post-attachments/v/0196540f-3f7c-79d1-a333-5a9412bd73e7)

# ๊ฐœ์š”

๋‚œ ๊ธฐ์ˆ ๊ณผ ๊ด€๋ จ๋œ ๊ธ€์„ ์จ์„œ ์ด ๋ธ”๋กœ๊ทธ์— ๊ฒŒ์žฌํ•˜๊ณ  ์žˆ๋‹ค. ์ตœ๊ทผ์—๋Š” ๋ธ”๋กœ๊ทธ ๊ธ€์„ [GeekNews์— ๋งํฌ๋กœ ๊ณต์œ ํ•œ ์ ](https://news.hada.io/topic?id=20309)์ด ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ฐ‘์ž๊ธฐ ๋ธ”๋กœ๊ทธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๊ฐ€ ์ž‘๋™ ๋ถˆ๋Šฅ์— ๋น ์ง€๋ฉด์„œ **๋ธ”๋กœ๊ทธ ์ ‘์† ์žฅ์• **๋ฅผ ๊ฒช์—ˆ๋‹ค. 

[^slashdot]: ์ด์ฒ˜๋Ÿผ '๋” ํฐ ๊ทœ๋ชจ์˜ ์›น์‚ฌ์ดํŠธ๋กœ๋ถ€ํ„ฐ์˜ ํŠธ๋ž˜ํ”ฝ ์œ ์ž…์œผ๋กœ ์ธํ•œ ์„œ๋น„์Šค ์žฅ์• '์„ "์Šฌ๋ž˜์‹œ๋‹ท ํšจ๊ณผ"๋ผ ํ•œ๋‹ค. [์œ„ํ‚ค๋ฐฑ๊ณผ - ์Šฌ๋ž˜์‹œ๋‹ท ํšจ๊ณผ](https://ko.wikipedia.org/wiki/%EC%8A%AC%EB%9E%98%EC%8B%9C%EB%8B%B7_%ED%9A%A8%EA%B3%BC)

๋กœ๊ทธ ๋ฐ ๋งคํŠธ๋ฆญ์„ ๋ถ„์„ํ•œ ๊ฒฐ๊ณผ, **๋ธ”๋กœ๊ทธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘์† ๋ถˆ๊ฐ€๋กœ ์ธํ•œ ์„œ๋น„์Šค ๊ฑฐ๋ถ€** ์ง•ํ›„๊ฐ€ ํ™•์ธ๋˜์—ˆ๋‹ค.

์ด ๊ธ€์—์„œ๋Š” ์žฅ์•  ์žฌ๋ฐœ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ํƒํ•œ ๊ฐœ์„  ๋ฐฉ์•ˆ๊ณผ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋กํ•œ๋‹ค.

๊ธ€์— ๊ธ€์–ด๊ฐ€๊ธฐ ์•ž์„œ, ์ด ๋ธ”๋กœ๊ทธ์˜ SLA[^sla]๋ฅผ ์ˆ˜์น˜ํ™”ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ € ๊ณต์œ ํ•˜๊ฒ ๋‹ค. ๊ฐœ์„  ์ „/ํ›„๋ฅผ ๋น„๊ตํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

- ๊ฐœ์„  ์ „: 51% (1๋ถ„๋‹น ์•ฝ 400ํšŒ ์š”์ฒญ์‹œ)
- ๊ฐœ์„  ํ›„: **99.9996286%** (๋ถ„๋‹น ์•ฝ 40,500ํšŒ ์š”์ฒญ์‹œ)

[^sla]: [Wikipedia - Service-level Agreement - Cloud Computing](https://en.wikipedia.org/wiki/Service-level_agreement#Cloud_computing) - "SLAs span across the cloud and are offered by service providers as a service-based agreements rather than a customer-based agreements. Measuring, monitoring and reporting on cloud performance is based on the end UX or their ability to consume resources."

# ์ ‘์† ์žฅ์•  ๋‹น์‹œ ์ƒํ™ฉ

![๋‚ด ๋ธ”๋กœ๊ทธ์˜ ์ ‘์† ๋ถˆ๊ฐ€ ์žฅ์•  ๋ฐœ์ƒ ์‚ฌ์‹ค์„ ์•Œ๋ ค์ค€ ๋Œ“๊ธ€](https://blog.atj.sh/post-attachments/v/019652b5-45dc-7d63-8545-4cf39ce42dee) *์‚ฌ์ง„: [์ถœ์ฒ˜](https://news.hada.io/comment?id=37108)*

2025๋…„ 4์›” 13์ผ ์˜ค์ „, ๋‚˜๋Š” ๋‚ด ๋ธ”๋กœ๊ทธ ๊ธ€์„ ํ•œ๊ตญ์–ด ๊ฐœ๋ฐœ ๋‰ด์Šค ์‚ฌ์ดํŠธ GeekNews์— ๋“ฑ๋กํ•˜์˜€๋‹ค[^blog-article] [^gn-article]. ์ดํ›„ GeekNews ๋ฐฉ๋ฌธ์ž๋“ค์ด ๋‚ด ๋ธ”๋กœ๊ทธ์— ์œ ์ž…๋˜์—ˆ๋‹ค [^slashdot]. 

๊ทธ๋Ÿฐ๋ฐ, ์ผ๋ถ€ ๋ฐฉ๋ฌธ์ž๋Š” ์ ‘์† ์žฅ์• ๋ฅผ ๊ฒช์—ˆ๋‹ค.

[^blog-article]: [https://blog.atj.sh/post/45](https://blog.atj.sh/post/45)

[^gn-article]: [GeekNews - ๊ทธ๋ƒฅ LLM์ด ์ฝ”๋“œ๋ฒ ์ด์Šค ์ „์ฒด๋ฅผ ์ดํ•ดํ•ด์ฃผ๋ฉด ์•ˆ ๋ ๊นŒ: ๋ฒˆ๋“ค๋ง์„ ํ†ตํ•œ RAG ์‹œ๋„
](https://news.hada.io/topic?id=20309)

## ํ…Œํฌ ์Šคํƒ

์ด ๋ธ”๋กœ๊ทธ์˜ ๊ฒŒ์‹œ๋˜๋Š” ๋ชจ๋“  ๊ธ€๊ณผ ์‚ฌ์ง„์— ๋Œ€ํ•œ CRUD๋ฅผ ๋‹ด๋‹นํ•˜๋Š”, **๋ธ”๋กœ๊ทธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„**์˜ ํ…Œํฌ ์Šคํƒ์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์š”์•ฝ๋œ๋‹ค.

- DB ํƒ€์ž…: PostgreSQL
- PostgreSQL ๋ฐฐํฌ์ฒ˜: [Supabase](https://supabase.com)
- SQL ํด๋ผ์ด์–ธํŠธ: [launchbadge/sqlx::postgresql](https://github.com/launchbadge/sqlx) (์ดํ•˜ "sqlx")
- ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋Š” ์„œ๋ฒ„๋ฆฌ์Šค ํ™˜๊ฒฝ(AWS Lambda)์— ๋ฐฐํฌ๋จ

[^blog-tech-stack] [^blog-image]

[^blog-tech-stack]: ๋ธ”๋กœ๊ทธ ์ „์ฒด์— ๋Œ€ํ•œ ํ…Œํฌ ์Šคํƒ์€ ๋‹ค๋ฅธ ๊ธ€์— ์ •๋ฆฌํ•ด ๋‘์—ˆ๋‹ค. [์ „์„ฑํ›ˆ์˜ ๋ธ”๋กœ๊ทธ - blog.atj.sh](https://blog.atj.sh/post/4)

[^blog-image]: [์ „์„ฑํ›ˆ์˜ ๋ธ”๋กœ๊ทธ - PostgreSQL๋ฅผ ์ด๋ฏธ์ง€ ์ €์žฅ์†Œ๋กœ ํ™œ์šฉํ•˜๊ธฐ](https://blog.atj.sh/post/33)

## ๋‹น์‹œ ํŠธ๋ž˜ํ”ฝ 

![](https://blog.atj.sh/post-attachments/v/019651d9-7233-7de3-8650-863ed38039ae)

๋ธ”๋กœ๊ทธ ์ ‘์† ์žฅ์•  ๋ฐœ์ƒ ์‹œ์ ์˜ ํŠธ๋ž˜ํ”ฝ ์ˆ˜์น˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

- ๋ธ”๋กœ๊ทธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์˜ ํ˜ธ์ถœ ๋นˆ๋„๋Š” ๋ถ„๋‹น ํ‰๊ท  96ํšŒ, ๋ถ„๋‹น ์ตœ๋Œ€ 400ํšŒ. 
- AWS Lambda concurrent execution ์ˆ˜์น˜๋Š” ๋ถ„๋‹น ์•ฝ 27๋‹จ์œ„[^aws-ce].

[^aws-ce]: ๋™์‹œ์— ์‹คํ–‰๋œ AWS Lambda ํ•จ์ˆ˜ ๊ฐœ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. [Amazon AWS Documentation - Understanding Lambda function scaling
](https://docs.aws.amazon.com/lambda/latest/dg/lambda-concurrency.html)

## ๋‹น์‹œ ์—๋Ÿฌ ๋กœ๊ทธ

์ ‘์† ๋ถˆ๊ฐ€ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•  ๋•Œ ๊ธฐ๋ก๋œ[^cloudwatch] ์—๋Ÿฌ ๋กœ๊ทธ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

[^cloudwatch]: ์„œ๋น„์Šค ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์œ„ํ•ด [Amazon Cloudwatch๋กœ ๋กœ๊ทธ๋ฅผ ์ˆ˜์ง‘](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html)ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

`thread 'main' panicked at src/main.rs:52:10: can't connect to database: PoolTimedOut`

sqlx์—์„œ [PoolTimedOut](https://docs.rs/sqlx/latest/sqlx/enum.Error.html#variant.PoolTimedOut) ์—๋Ÿฌ๋ฅผ ์ผ์œผํ‚จ ๊ฒƒ์œผ๋กœ ํ™•์ธ๋œ๋‹ค. 

## ์ค‘๊ฐ„ ์ •๋ฆฌ

1. ์‹œ์Šคํ…œ์ด ๊ฐ๋‹นํ•˜์ง€ ๋ชปํ•˜๋Š” ํŠธ๋ž˜ํ”ฝ ์œ ์ž…์ด ๋ฐœ์ƒํ•˜์˜€๋‹ค.
2. ํŠธ๋ž˜ํ”ฝ์— ๋Œ€์‘ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ์„œ๋ฒ„๊ฐ€ ๋™์‹œ์— ์ƒ์„ฑ๋˜์—ˆ๋‹ค.
3. ๊ฐ ์„œ๋ฒ„๊ฐ€ 1๊ฐœ์˜ PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผ์„ ์‹œ๋„ํ•˜์˜€๋‹ค.
4. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ž์›์ด ๋น ๋ฅด๊ฒŒ ์†Œ์ง„๋˜์—ˆ๊ณ  ๊ฒฐ๊ตญ ๊ณ ๊ฐˆ๋˜์ž, ์ผ๋ถ€ ์„œ๋ฒ„๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ์„ ์‹คํŒจํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฒŒ์–ด์กŒ๋‹ค.
5. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„ ์ ‘๊ทผ์— ์‹คํŒจํ•œ ์„œ๋ฒ„๋“ค์€ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ฐ•์ œ ์ข…๋ฃŒํ•˜์˜€๊ณ , **๋„คํŠธ์›Œํฌ ์‘๋‹ต์„ ๊ฑฐ๋ถ€**ํ•˜์˜€๋‹ค.

์ฆ‰, **๋ธ”๋กœ๊ทธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„**์˜ **๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘์† ์‹คํŒจ**๊ฐ€ ์ด์Šˆ ๋ฐœ์ƒ ์ง€์ ์ด๋‹ค.

# ์ด์Šˆ ์›์ธ ๋ถ„์„

์ด์Šˆ ์›์ธ ๋ถ„์„์— ์•ž์„œ, ์ด ๋ธ”๋กœ๊ทธ๋Š” ์ด 2๋‹จ๊ณ„์˜ ์ปค๋„ฅ์…˜ ํ’€์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ๋Š” ์ด ์ปค๋„ฅ์…˜ ํ’€ ๊ด€๋ฆฌ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด ๋ฐœ์ƒํ•œ ์žฅ์• ์ธ๋ฐ, ๊ทธ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

## 1์ฐจ ์ปค๋„ฅ์…˜ ํ’€: Supabase์˜ PostgreSQL Connection Pooler

![](https://blog.atj.sh/post-attachments/v/0196527d-8969-7e40-aec4-653bc624f09c) *[์‚ฌ์ง„ ์ถœ์ฒ˜: Supabase Documentation - Connecting to your database](https://supabase.com/docs/guides/database/connecting-to-postgres#connection-pooler)*

Supabase๋Š” PostgreSQL SaaS๋กœ์จ, **๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์ž์ฒด์ ์ธ ์ปค๋„ฅ์…˜ ํ’€์„ ์ œ๊ณต**ํ•œ๋‹ค.

Supabase์˜ 'Connection Pooler'๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปค๋„ฅ์…˜ ํ’€์„ ํ†ตํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ์ด ๋ณด์žฅ๋œ๋‹ค. ์ง์ ‘ ์ ‘๊ทผ ๋ฐฉ์‹๋ณด๋‹ค ์ข€ ๋” ๋น ๋ฅธ ์ปค๋„ฅ์…˜ ํš๋“์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

[^supabase]: ๊ณต์‹ ๋ฌธ์„œ: [Supabase Database Documentation - Connect to your database](https://supabase.com/docs/guides/database/connecting-to-postgres)

ํ•œํŽธ, ๋ธ”๋กœ๊ทธ ์„œ๋ฒ„๋Š” prepared statements๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ ๋‚ด ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์น˜ํ™˜ํ•œ๋‹ค. sqlx๋Š” ์ด๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์ง€์›ํ•˜๊ณ  ์žˆ์œผ๋‚˜[^sqlx-prep], Supabase์˜ "transaction mode connection pooler"๋Š” ํ˜„์žฌ prepared statements๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค[^supabase-tp].

[^sqlx-prep]: [launchbadge/sqlx/README.md](https://github.com/launchbadge/sqlx?tab=readme-ov-file#querying) - "When using the high-level query API (sqlx::query), statements are prepared and cached per connection."

[^supabase-tp]: [Supabase Database Documentation - Connect to your database - Supavisor transaction mode](https://supabase.com/docs/guides/database/connecting-to-postgres#supavisor-transaction-mode) - "Transaction mode does not support prepared statements. To avoid errors, turn off prepared statements for your connection library."

๋”ฐ๋ผ์„œ ๋‚˜๋Š” prepared statements๊ฐ€ ์ง€์›๋˜๋Š” Connection Pooler๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด, Supabase์˜ "session mode connection pooler"๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘์†ํ•˜๋„๋ก ํ–ˆ๋‹ค.

์ด๋•Œ ์ปค๋„ฅ์…˜ ํ’€ ์„ค์ •์„ Supabase ๋Œ€์‹œ๋ณด๋“œ์—์„œ ์ง์ ‘ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค[^poolsize]. Supabase์˜ pool size ๊ธฐ๋ณธ๊ฐ’์€ 15์ด๋‹ค. ๋‚˜๋Š” ๊ธฐ๋ณธ๊ฐ’ ๊ทธ๋Œ€๋กœ ๋ฐฐํฌํ•˜์˜€๋‹ค.

[^poolsize]: [Supabase Database Documentation - Connection management](https://supabase.com/docs/guides/database/connection-management)

## 2์ฐจ ์ปค๋„ฅ์…˜ ํ’€: ๋ฐฑ์—”๋“œ ๋‚ด๋ถ€

Supabase์˜ 1์ฐจ์ ์ธ ์ปค๋„ฅ์…˜ ํ’€๊ณผ ๋ณ„๊ฐœ๋กœ 2์ฐจ์ ์ธ ์ปค๋„ฅ์…˜ ํ’€์„ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ์•ˆ์— ๋‘๊ณ  ์‹ถ์—ˆ๊ธฐ์—, ๋‚˜๋Š” sqlx ๋ฌธ์„œ์— ์†Œ๊ฐœ๋œ ์ปค๋„ฅ์…˜ ํ’€ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๊ฑฐ์˜ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜์—ฌ ๋‚ด ์ฝ”๋“œ์— ๋ถ™ํ˜€๋„ฃ์—ˆ๋‹ค.

```rust
use sqlx::postgres::PgPoolOptions;

let pg_pool = PgPoolOptions::new()
    .max_connections(5)
    .acquire_timeout(Duration::from_secs(3))
    .connect(&db_connection_str)
    .await
    .expect("can't connect to database");

let conn = pg_pool.acquire().await.map_err(|_| internal_error())?;
```

## 2์ฐจ ์ปค๋„ฅ์…˜ ํ’€์˜ ์ด์Šˆ

์ด๋ฒˆ ์ด์Šˆ๋ฅผ ํ™•์ธํ•˜๋ฉด์„œ ๋ฐฑ์—”๋“œ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•˜์˜€๋‹ค. ์œ„ ์ฝ”๋“œ์˜ ์ง„์งœ ์˜๋ฏธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์•˜๋‹ค.

- ์ตœ์ดˆ์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜์„ 0๊ฐœ๋งŒ ์ ์œ ํ•จ.
- ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ๋ถ€ํ„ฐ ์ปค๋„ฅ์…˜์„ ์ƒˆ๋กญ๊ฒŒ 1๊ฐœ ์ ์œ ํ•ด์˜ค๊ณ , ์„œ๋ฒ„ ๋‚ด ์ปค๋„ฅ์…˜ ํ’€์— ๋“ฑ๋ก.
- ์ปค๋„ฅ์…˜ ํ’€์— ๋“ฑ๋ก๋œ ์ปค๋„ฅ์…˜์€ ์„œ๋ฒ„ ์•ˆ์—์„œ๋งŒ ์žฌ์‚ฌ์šฉํ•จ.
- ์„œ๋ฒ„ ๋‚ด ์ปค๋„ฅ์…˜ ํ’€์— ์ตœ๋Œ€ 5๊ฐœ ์ปค๋„ฅ์…˜์„ ์ ์œ  ๊ฐ€๋Šฅ.
- ํ•œ ๋ฒˆ ์ ์œ ํ•ด์˜จ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜์€ 10๋ถ„ ๋’ค์— ์ž๋™์œผ๋กœ ๋ฐ˜ํ™˜.
- ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜์„ ์ƒˆ๋กญ๊ฒŒ ์ ์œ ํ•ด์˜ฌ ๋•Œ ๋งŒ์•ฝ 3์ดˆ ์•ˆ์— ํš๋“ํ•ด์˜ค์ง€ ๋ชปํ•˜๋ฉด ์„œ๋ฒ„ ๊ฐ•์ œ ์ข…๋ฃŒ ์ฒ˜๋ฆฌ.

ํŠนํžˆ, "์ปค๋„ฅ์…˜์„ 10๋ถ„ ๋’ค ๋ฐ˜ํ™˜"ํ•˜๋Š” ๊ฒƒ์€ **sqlx ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ž๋™ ๊ธฐ๋ณธ๊ฐ’**์ด๊ธฐ์—[^sqlx-default], ๋ณ„๋„๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์€ ๋‚ด ์˜๋„์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์ ์šฉ๋œ ์ •์ฑ…์ธ ์…ˆ์ด๋‹ค.

๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋จผ์ €, '๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ'๊ฐ€ ๋™์‹œ์— 15ํšŒ ๋ฐœ์ƒํ•˜์˜€๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์ฆ‰์‹œ 15๊ฐœ์˜ AWS Lambda ์„œ๋ฒ„๊ฐ€ ์ƒ์„ฑ๋  ๊ฒƒ์ด๋‹ค. ์ด๋•Œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜์„ ๊ฐ์ž 1๊ฐœ์”ฉ ์ ์œ ํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋Š” Supabase์˜ pool size ๊ธฐ๋ณธ๊ฐ’์ธ 15๊ฐœ ์ „๋ถ€๋ฅผ ๋ฒŒ์จ ์ ์œ ํ•ด๋ฒ„๋ฆฌ๊ฒŒ ๋˜๋Š” ์…ˆ์ด๋‹ค.

์•ž์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ์™€์ค‘, '๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ'๊ฐ€ ๋”ฑ 1๊ฑด ๋” ๋ฐœ์ƒํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ์•ž์„œ ์ƒ์„ฑ๋œ 15๊ฐœ์˜ AWS Lambda ์„œ๋ฒ„๋“ค์€ ์•„์ง ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋А๋ผ ๋ฐ”์˜๊ธฐ์—, ์ƒˆ๋กœ์šด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด 16๋ฒˆ์งธ AWS Lambda ์„œ๋ฒ„๊ฐ€ ์ƒ์„ฑ๋  ๊ฒƒ์ด๋‹ค. ์ด ์„œ๋ฒ„ ๋˜ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜ ์ ์œ ๋ฅผ ์‹œ๋„ํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ Supabase๋Š” ๋” ์ด์ƒ ํ• ๋‹น์‹œํ‚ฌ ์ปค๋„ฅ์…˜ ์ž์›์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ ์œ  ๋Œ€๊ธฐ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. 

์•ž์„œ ์ƒ์„ฑ๋œ 15๊ฐœ์˜ ์„œ๋ฒ„๋“ค์€ ์ตœ์žฅ 10๋ถ„๊ฐ„ ์ปค๋„ฅ์…˜ ์ž์›์„ ๋‚ด๋†“์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ์ด์— 16๋ฒˆ์งธ ์„œ๋ฒ„๋Š” ์ปค๋„ฅ์…˜ ์ง€์—ฐ์„ ๊ธฐ๋‹ค๋ฆฌ๋‹ค 3์ดˆ๊ฐ€ ์ง€๋‚˜๋ฒ„๋ฆฌ๋Š” ์ˆœ๊ฐ„, ํ•ด๋‹น ์„œ๋ฒ„๋Š” ๊ฐ•์ œ ์ข…๋ฃŒ๋˜๊ณ  ์‘๋‹ต์— ์‹คํŒจํ•˜๊ฒŒ ๋œ๋‹ค. 17๋ฒˆ์งธ, 18๋ฒˆ์งธ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋”๋ผ๋„, ์ปค๋„ฅ์…˜ ์ž์›์ด ๊ณ ๊ฐˆ๋œ ์ด์ƒ ์‘๋‹ต์— ์‹คํŒจํ•  ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.

์ฆ‰, 2์ฐจ ์ปค๋„ฅ์…˜ ํ’€์˜ ์ž˜๋ชป๋œ ์„ค์ •์œผ๋กœ ์ธํ•ด, 1์ฐจ ์ปค๋„ฅ์…˜ ํ’€์„ ๋ชจ๋‘ ์†Œ์ง„ํ•˜๊ณ  ์ž์› ๊ณ ๊ฐˆ์„ ๋ฐœ์ƒ์‹œํ‚จ ์…ˆ์ด๋‹ค.

## ์ตœ์ข… ์ •๋ฆฌ

![](https://blog.atj.sh/post-attachments/v/01965314-0178-79a2-b6f5-06ad2213788f)

๋ธ”๋กœ๊ทธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋Š” Supabase์˜ 1์ฐจ์ ์ธ ์ปค๋„ฅ์…˜ ํ’€์—์„œ ์ปค๋„ฅ์…˜์„ ํš๋“ํ•ด์˜ค๊ณ  ์žˆ์—ˆ๋‹ค. 1์ฐจ ์ปค๋„ฅ์…˜ ํ’€์˜ ์‚ฌ์ด์ฆˆ๋Š” 15๊ฐœ๋กœ ๋‹ค์†Œ ํ•œ์ •์ ์ธ ์ƒํ™ฉ์ด์—ˆ๋‹ค.

๋ธ”๋กœ๊ทธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๊ฐ€ ์•ž์„œ ๊ฐ€์ ธ์˜จ ์ปค๋„ฅ์…˜์„ ์„œ๋ฒ„ ๋‚ด๋ถ€์— ๋ณด๊ด€ํ•˜๋Š” 2์ฐจ์ ์ธ ์ปค๋„ฅ์…˜ ํ’€์„ ์ƒ์„ฑํ•˜๋„๋ก ๊ตฌํ˜„๋˜์—ˆ๋Š”๋ฐ, pool size๋Š” 5๊ฐœ๋กœ ์ ์—ˆ์ง€๋งŒ ์ปค๋„ฅ์…˜ ์ ์œ  ํ›„ ๋ฐ˜ํ™˜ ์ „ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด 10๋ถ„์œผ๋กœ ๊ณผ๋„ํ•˜๊ฒŒ ๊ธธ์—ˆ๋‹ค.

ํ•œํŽธ, 2์ฐจ ์ปค๋„ฅ์…˜ ํ’€์€ ๊ฐ ์„œ๋ฒ„ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋ฉฐ, ๋‹ค๋ฅธ ์„œ๋ฒ„์™€ ๊ณต์œ ๋˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค.

![](https://blog.atj.sh/post-attachments/v/01965314-0a3a-7070-b234-250cce770675)

์ด๋Ÿฌํ•œ 2์ฐจ ์ปค๋„ฅ์…˜ ํ’€ ์ƒ์„ฑ์œผ๋กœ ์ธํ•ด Supabase ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜ ์ž์›์ด ์™„์ „ํžˆ ์†Œ๋ชจ๋˜์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ 2์ฐจ ์ปค๋„ฅ์…˜ ํ’€์—์„œ๋Š” ํ•œ ๋ฒˆ ์ ์œ ํ•ด์˜จ ์ปค๋„ฅ์…˜์„ ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์•˜๊ธฐ์—, 1์ฐจ ์ปค๋„ฅ์…˜ ํ’€์˜ ์ž์› ๊ณ ๊ฐˆ ์ƒํƒœ๊ฐ€ ์ผ์ • ์‹œ๊ฐ„ ์œ ์ง€๋˜์—ˆ๋‹ค.

์ž์› ๊ณ ๊ฐˆ ์ƒํƒœ์—์„œ ์ปค๋„ฅ์…˜์„ ์‹œ๋„ํ•œ ์„œ๋ฒ„ ํ”„๋กœ์„ธ์Šค๋Š” ์ „๋ถ€ ๊ฐ•์ œ ์ข…๋ฃŒ๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋‚ณ์•˜๊ณ , ์ด๋Š” ์„œ๋ฒ„ ์‹œ์Šคํ…œ์˜ ์ „์ฒด์ ์ธ ์‘๋‹ต ๊ฑฐ๋ถ€๋กœ ์ด์–ด์กŒ๋‹ค.

# ๊ฐœ์„  ๋ฐฉ์•ˆ

์ผ๋‹จ 1์ฐจ ์ปค๋„ฅ์…˜ ํ’€ ์ •์ฑ…์„ ์ตœ๋Œ€ ์ˆ˜์ค€์œผ๋กœ ๋Š˜๋ ธ๋‹ค. Supabase ๋ฌด๋ฃŒ ํ”Œ๋žœ์—์„œ๋Š” pool size๋ฅผ 48๊ฐœ๊นŒ์ง€ ๋Š˜๋ฆด ์ˆ˜ ์žˆ๊ธฐ์— ๋ฐ”๋กœ ์ ์šฉํ•˜์˜€๋‹ค.

๊ทธ๋ฆฌ๊ณ  2์ฐจ ์ปค๋„ฅ์…˜ ํ’€ ์ •์ฑ…์„ ์ตœ์†Œ ์ˆ˜์ค€์œผ๋กœ ์ค„์˜€๋‹ค. ์„œ๋ฒ„ ๋‚ด ์ปค๋„ฅ์…˜ ํ’€ ๊ด€๋ฆฌ ์ •์ฑ…์„ ์†๋ณด์•˜๋‹ค[^commit].

[^commit]: [https://github.com/atjsh/rust-blog/commit/a757834af7d9204684ae5a865922e9eb5d3659c5](https://github.com/atjsh/rust-blog/commit/a757834af7d9204684ae5a865922e9eb5d3659c5)

```
let pg_pool = PgPoolOptions::new()
     .max_connections(1)
     .acquire_timeout(Duration::from_secs(3))
     .idle_timeout(Duration::from_secs(3))
     .connect(&db_connection_str)
     .await
     .expect("can't connect to database");
```

์˜๋ฏธ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

- ํ•œ ์„œ๋ฒ„์—์„œ ๋™์‹œ์— ์ ์œ  ๊ฐ€๋Šฅํ•œ ์ตœ๋Œ€ ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜๋Š” 1๊ฐœ.
- ํ•œ ๋ฒˆ ์ ์œ ํ•ด์˜จ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜์€ ์‚ฌ์šฉ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•˜์—ฌ 3์ดˆ ๋’ค์— ์ž๋™์œผ๋กœ ๋ฐ˜ํ™˜.

2์ฐจ ์ปค๋„ฅ์…˜ ํ’€์„ ์ตœ์†Œํ•œ์œผ๋กœ ์œ ์ง€ํ•˜์—ฌ ์„œ๋ฒ„ ๋‚ด ์ปค๋„ฅ์…˜ ์žฌํ™œ์šฉ์„ ๊ฐ€๋Šฅ์ผ€ ํ•˜๋Š” ๋™์‹œ์—, ๋„ˆ๋ฌด ์˜ค๋ž˜ ์ปค๋„ฅ์…˜์„ ์ ์œ ํ•˜์ง€ ์•Š๊ฒŒ ์ˆ˜์ •ํ•˜์—ฌ 1์ฐจ ์ปค๋„ฅ์…˜ ํ’€์ด ํ•ญ์ƒ ์—ฌ์œ ๋กญ๋„๋ก ๊ฐœ์„ ํ•˜์˜€๋‹ค. ๋™์‹œ์— 1์ฐจ ์ปค๋„ฅ์…˜ ํ’€์˜ ํฌ๊ธฐ๋ฅผ ํ‚ค์›Œ ๋งŽ์€ ์–‘์˜ ์ปค๋„ฅ์…˜์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€๋‹ค.

# ๊ฐœ์„ ์•ˆ ๊ฒ€์ฆ

![](https://blog.atj.sh/post-attachments/v/01965237-df90-7ff3-9992-8e768b1c8319) *์‚ฌ์ง„: [๋ถ€ํ•˜ ํ…Œ์ŠคํŒ… ์„œ๋น„์Šค 'loadster'](https://loadster.app/)๋กœ ์ด ๋ธ”๋กœ๊ทธ์— ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์˜€๋‹ค.*

![](https://blog.atj.sh/post-attachments/v/01965253-9253-7fb1-b2f0-a3f0b0563697) *์‚ฌ์ง„: ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์ด๋ฃจ์–ด์ง„ ํ›„ AWS Lambda ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•œ ๋งคํŠธ๋ฆญ.*

๊ฐœ์„ ์ ์„ ์ „๋ถ€ ์ ์šฉํ•œ ํ›„ ์ผ๋ถ€๋Ÿฌ ๋” ๊ทน์‹ฌํ•œ ํŠธ๋ž˜ํ”ฝ์„ ์„ค์ •ํ•˜๊ณ  ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์˜€๋‹ค. 

๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ๋Š” 3๋ถ„ ๋‚ด์™ธ ์‹œ๊ฐ„๋™์•ˆ ์ง„ํ–‰๋˜์—ˆ์œผ๋ฉฐ, ๋ถ€ํ•˜์˜ ์ •์ ์„ ์ฐ์—ˆ์„ ๋•Œ์—๋Š” 1๋ถ„๊ฐ„ ์•ฝ 40,500ํšŒ ์ •๋„์˜ ์š”์ฒญ์ด ์„œ๋ฒ„์— ์ „์†ก๋˜์—ˆ๋‹ค.

## ๊ฐœ์„ ์•ˆ ๊ฒ€์ฆ ๊ฒฐ๊ณผ

Amazon CloudWatch์— ๊ธฐ๋ก๋œ ์„œ๋ฒ„ ๋กœ๊ทธ๋ฅผ ์ง‘๊ณ„ํ•œ ๊ฒฐ๊ณผ, 107,705ํšŒ์˜ ์ „์ฒด ์š”์ฒญ ์ค‘ ์‘๋‹ต ๊ฑฐ๋ถ€ ์‚ฌ๋ก€๊ฐ€ ์ด 40ํšŒ ๋ฐœ๊ฒฌ๋˜์—ˆ๋‹ค.

์ตœ์†Œ ์„œ๋น„์Šค ๊ฐ€์šฉ์„ฑ์„ ์ˆ˜์น˜ํ™”ํ•ด๋ณธ ๊ฒฐ๊ณผ๊ฐ€ ์žฌ๋ฏธ์žˆ๋‹ค.
- ๊ธฐ์กด: 51% (1๋ถ„๋‹น ์•ฝ 400ํšŒ ์š”์ฒญ์‹œ)
- ํ˜„์žฌ: 99.9996286% (1๋ถ„๋‹น ์•ฝ 40,500ํšŒ ์š”์ฒญ์‹œ)

# ๊ฒฐ๋ก 

๋ธ”๋กœ๊ทธ์—์„œ ๋ฐœ์ƒํ–ˆ๋˜ ์ ‘์† ๋ถˆ๋Šฅ ์žฅ์•  ์›์ธ์„ ์„ฑ๊ณต์ ์œผ๋กœ ํŒŒ์•…ํ•˜์˜€๊ณ , ์žฅ์•  ๋ฐœ์ƒ๋ฅ ์„ "์‚ฌ์‹ค์ƒ ๊ทน๋ณตํ–ˆ๋‹ค"๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€๊นŒ์ง€ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋‹คํ–‰ํžˆ๋„ ๋น„์šฉ ๋ถ€๋‹ด์ด ๋ณ„๋„๋กœ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋‹ค๋ฃจ๋Š” ํ˜„ํ–‰ ๊ตฌ์กฐ๋ฅผ ํฌ๊ฒŒ ๋ฐ”๊พธ์ง€ ์•Š์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

# ์†Œ๊ฐ

๊ฒฐ๋ก ์ ์œผ๋กœ๋Š”, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์–ด๋–ค ๊ธฐ๋ณธ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ๊ตฌ์„ฑ๋˜๋Š”์ง€[^sqlx-default] ํ™•์ธํ•˜์˜€๋‹ค๋ฉด ๋ง‰์„ ์ˆ˜ ์žˆ์—ˆ์„ ๊ฒƒ ๊ฐ™์•„์„œ, ํ™•์ธ์ด ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์ด ์•„์‰ฝ๊ฒŒ ๋А๊ปด์ง„๋‹ค. ๊ทธ๋ฆฌ๊ณ , ์‚ฌ์ „ ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ์˜ ์ค‘์š”์„ฑ์„ ๋‹ค์‹œ๋” ๋А๊ฒผ๋‹ค. 

์ด๋ฒˆ ์žฅ์• ๊ฐ€ ๋‚˜์—๊ฒŒ ์žˆ์–ด์„œ๋Š”, '์†Œ์Šค ์ฝ”๋“œ ์•ˆ์—์„œ๋Š” ๋ณด์ด์ง€ ์•Š๋Š” ๋ถ€๋ถ„๋“ค์„ ๊ฒ€์ฆํ•˜๋Š” ์ž‘์—…'์˜ ์ค‘์š”์„ฑ์„ ๋ป์ €๋ฆฌ๊ฒŒ ๋А๋ผ๋Š” ๊ณ„๊ธฐ๊ฐ€ ๋˜์—ˆ๋‹ค.

[^sqlx-default]: sqlx์˜ ์ปค๋„ฅ์…˜ ํ’€ ์ƒ์„ฑ ์˜ต์…˜์˜ ๊ธฐ๋ณธ๊ฐ’๋“ค์€  [launchbadge/sqlx - PoolOptions::new()](https://github.com/launchbadge/sqlx/blob/91d26bad4d5e2b05fab1c86d0fbe11586d30f29d/sqlx-core/src/pool/options.rs#L143-L166)์—์„œ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.