blog — hoatq.dev

find ./blog -type f -name "*.md" | sort -r

found 50 entries

databasepostgresqlperformancebackenddevops
Postgres partitioning theo thời gian: bảng 500 triệu dòng không còn là nỗi sợ

Bảng events/logs/orders lên vài trăm triệu dòng thì VACUUM chạy hàng giờ, index phình to, query cũ lôi cả bảng vào cache. Declarative partitioning theo tháng cho phép drop partition cũ tức thì, query mới chỉ scan 1 partition, autovacuum không còn nghẹt. Bài này đi từ setup, pg_partman, đến các bẫy mình từng dính.

backendmicroservicesreliabilityperformanceobservability
Timeout budget & deadline propagation: cách tránh request treo trong microservice

Mỗi service tự đặt timeout 30s, chain 5 hop thành 150s — user chờ 30 giây rồi bỏ đi trong khi backend vẫn cày như chưa từng bị bỏ rơi. Bài này nói về timeout budget, deadline propagation, và vì sao "timeout tĩnh" là bug thiết kế trong hệ thống phân tán.

backendpostgresperformancedatabasepython
Bulk insert Postgres: COPY vs UNNEST vs multi-VALUES — chọn cái nào cho tốc độ

Import 500K dòng vào Postgres, ba cách phổ biến chênh nhau 20-40 lần tốc độ. Bài này benchmark COPY, INSERT với unnest, và multi-row VALUES trên cùng dataset; giải thích vì sao chậm/nhanh; và khi nào chọn cái nào — kèm mấy pitfall dễ mắc với psycopg và SQLAlchemy.

backendpostgresdistributed-systemsconcurrencydatabase
Postgres Advisory Lock: điều phối worker không cần Redis

Cron chạy trùng trên 3 pod, leader election cần dependency mới, distributed lock kiểu Redis nhưng vẫn muốn rollback theo transaction — tất cả đều giải được bằng pg_advisory_lock có sẵn trong Postgres. Bài này mổ xẻ session-level vs transaction-level, hai sai lầm dễ mắc với connection pool, và khi nào nên đừng dùng nó.

backendperformanceobservabilitybenchmarkingreliability
Tail latency p99: vì sao trung bình nói dối và coordinated omission ăn gian benchmark

Average latency 50ms nghe rất ổn, nhưng 1% request chậm 5 giây có thể làm sập trải nghiệm. Bài này giải thích vì sao p99 quan trọng hơn average, coordinated omission làm benchmark đẹp giả tạo thế nào, và cách đo latency cho đúng trong production.

pythonfastapiasyncperformancebackend
Blocking event loop trong FastAPI: những lỗi async tưởng nhỏ nhưng giết throughput

Vì sao một dòng requests.get hay bcrypt.hashpw trong endpoint async có thể làm sập throughput của FastAPI xuống chỉ còn vài request/giây — và cách phát hiện, đo đạc, sửa cho đúng.

databasepostgresqlperformancebackendresilience
Read Replica Lag: vì sao user vừa tạo xong đã không thấy đâu

Thêm read replica để giảm tải DB là pattern phổ biến, nhưng dễ dính bug khó chịu: user POST xong, GET ngay lại thì thấy "không có gì". Bài này mổ xẻ read-after-write consistency, replication lag, và 4 chiến lược fix thực tế kèm code FastAPI + Postgres.

backendpostgresqlperformancedatabaseoperations
Postgres VACUUM và table bloat: hiểu để không sợ khi DB phình to

Table 10 triệu row mà size trên đĩa 80GB, query chậm dần dù index vẫn còn. Thủ phạm thường là bloat — và autovacuum không chạy kịp. Bài này mổ xẻ cách Postgres lưu version row, vì sao VACUUM cần thiết, làm sao đo bloat, và tune autovacuum mà không cần đến VACUUM FULL trong production.

backendsecurityapi-designwebhookpython
Webhook security: HMAC signature và chống replay attack đúng cách

Vì sao chỉ kiểm tra IP whitelist hoặc secret token trong header là không đủ, và cách triển khai HMAC signature + timestamp đúng chuẩn Stripe/GitHub để webhook không bị giả mạo hay replay — kèm code Python.

backendpostgresqlreal-timepub-subarchitecture
Postgres LISTEN/NOTIFY: pub/sub real-time không cần Redis hay Kafka

Nhiều team cài thêm Redis chỉ để làm pub/sub cho vài trăm event mỗi phút. Postgres có sẵn LISTEN/NOTIFY từ thời 7.x, đủ để làm cache invalidation, push WebSocket, hay trigger background job. Bài này mổ xẻ cách dùng, giới hạn thật sự, và khi nào nên đổi sang broker.

aitestingqaproductivity
Hướng dẫn sử dụng AI để tạo test case cho tester — từ requirement đến test suite

Workflow thực tế cho QA/tester dùng AI sinh test case chất lượng. Áp dụng các kỹ thuật BVA, equivalence partitioning, decision table và viết test case theo format chuẩn.

backendpostgresqljob-queueconcurrencyperformance
SELECT FOR UPDATE SKIP LOCKED: biến PostgreSQL thành job queue

Khi nào bạn không cần Redis, RabbitMQ hay SQS để chạy background job. Bài này mổ xẻ SKIP LOCKED — vũ khí ít người dùng của Postgres — để xây job queue đơn giản, đáng tin, chỉ với một bảng và vài chục dòng code.

backendmicroservicesdesign-patternevent-drivendistributed-systems
Saga Pattern: quản lý transaction phân tán trong microservices

Khi một nghiệp vụ trải dài qua nhiều service và không thể dùng ACID transaction, Saga Pattern là cách giữ cho dữ liệu consistent — kèm ví dụ orchestration và choreography với FastAPI.

backenddatabaseormsqlalchemyperformance
N+1 query: kẻ giết hiệu năng âm thầm của ORM và cách dập tắt

Một endpoint trả về 50 đơn hàng nhưng log DB thấy 200+ query. Đó là N+1 — lỗi kinh điển nhất của ORM. Bài này mổ xẻ vì sao nó xảy ra, cách phát hiện sớm, và bốn cách fix với SQLAlchemy: selectinload, joinedload, dataloader pattern, và denormalize có chủ ý.

backenddatabasepostgresqlperformancepgbouncer
Connection pool sizing: vì sao tăng pool size lại làm app chậm hơn

Sếp bảo "API chậm, tăng pool size lên đi" — và sau khi tăng từ 20 lên 200, API chậm gấp đôi. Bài này mổ xẻ vì sao pool size lớn lại phản tác dụng, công thức tính pool size đúng, và cách tune cho FastAPI + PgBouncer + PostgreSQL.

backenddevopsrelease-managementdesign-patternproduction
Feature Flags & Progressive Rollout: deploy tính năng mới mà không sợ vỡ trận

Tách deploy ra khỏi release để có thể bật/tắt tính năng tức thì, rollout dần theo phần trăm user, và kill switch khi sự cố. Bài này mổ xẻ feature flag pattern, các loại flag, và một implementation Python/Postgres dùng được trong production.

databasepostgresqlperformancebackenddesign-pattern
UUID v7: ID có thứ tự thời gian, cứu B-tree index khỏi fragmentation

UUID v4 random rất tiện nhưng giết hiệu năng B-tree index khi bảng lớn. UUID v7 (RFC 9562) chèn timestamp vào prefix, vừa giữ tính ngẫu nhiên vừa cho insert tuần tự. Bài này so sánh v4 vs v7 trên Postgres bằng số đo thực tế, kèm code Python và SQL.

backendpostgresqlconcurrencydesign-patternsqlalchemy
Optimistic Locking: tránh lost update với version column

Hai user cùng sửa một record, ai save sau thì ghi đè người trước — bug kinh điển "lost update". Bài này đi qua optimistic locking với version column: cách triển khai trong PostgreSQL/SQLAlchemy, retry khi conflict, xử lý phía UI, và khi nào nên dùng nó thay vì pessimistic lock.

observabilityopentelemetrymicroservicesperformancebackend
OpenTelemetry distributed tracing: tìm bottleneck trong microservices không cần đoán mò

Khi một request đi qua 6 service và chậm 3 giây, log thường vô dụng vì bạn không biết bottleneck nằm ở đâu. Bài này chia sẻ cách mình setup OpenTelemetry cho FastAPI + Node, propagate trace context qua HTTP và message queue, và những bài học sau khi trace giúp tìm ra hai vụ N+1 ẩn trong production.

backendpostgresqlperformanceapi-designdatabase
Cursor pagination: vì sao OFFSET càng ngày càng chậm và cách fix

Trang 1 load 50ms, trang 1000 load 5 giây — cùng một query, cùng một limit. Bài này giải thích vì sao OFFSET là cái bẫy âm thầm trong mọi API phân trang, và cách chuyển sang cursor-based pagination cho Postgres với keyset index đúng chuẩn.

pythonperformancedebuggingobservability
memray — tìm memory leak Python như dân anh Bloomberg

Chia sẻ cách mình dùng memray (memory profiler của Bloomberg) để tìm memory leak trong Python production — flamegraph, live mode, pytest plugin và những tip thực tế từ một lần debug OOM lúc nửa đêm.

aiclaude-codedeveloper-toolsproductivityworkflow
Cấu trúc file SKILL.md: tái sử dụng instruction cho Claude Code và AI agent

Mỗi lần mở chat với AI là lặp lại hướng dẫn "hãy commit theo conventional commits...", "review code tập trung vào security...". SKILL.md giải quyết vấn đề đó — mổ xẻ cấu trúc, frontmatter, và cách thiết kế skill tái dùng được cho Claude Code.

aiclaude-codedeveloper-toolsautomationworkflow
Hooks trong Claude Code: bắt buộc tuân theo quy ước mà không cần nhắc agent

Thay vì dặn AI "nhớ cập nhật CLAUDE.md sau khi sửa code" mỗi session, hook chạy tự động sau mỗi Edit/Write và nhắc giùm. Bài này đi qua các sự kiện, định dạng JSON đầu vào, và các tình huống thực dụng — kèm ví dụ hook thật đang chạy production.

aiclaude-codedeveloper-toolsarchitectureworkflow
Subagent trong Claude Code: thiết kế agent chuyên môn hóa cho codebase lớn

Main agent không nên tự làm tất cả. Subagent là cách chia việc cho "AI chuyên khoa" — mỗi cái có context riêng, tool set riêng, model riêng. Bài này mổ xẻ AGENT.md, cách delegate đúng, và những bẫy mình từng dính khi thiết kế 12 subagent cho monorepo production.

aiclaude-codedeveloper-toolsconfigurationworkflow
Tìm hiểu folder .claude: cấu trúc và cấu hình Claude Code

Mở một project có dùng Claude Code bạn sẽ thấy folder .claude với agents, skills, hooks, settings. Bài này dẫn bạn đi qua toàn bộ cấu trúc — global vs project, nên commit cái gì, gitignore cái gì, và cách tổ chức để cả team dùng chung.

backendkubernetesdockerdevopsreliability
Graceful shutdown trong container: đừng để SIGTERM làm rớt request

Mỗi lần rolling deploy là một nhóm request đang chạy bị cắt ngang, khách hàng nhận 502, payment lưng chừng. Bài này mổ xẻ vòng đời SIGTERM trong Kubernetes và cách làm graceful shutdown đúng cho FastAPI, Node.js và worker — kèm lesson học được từ production.

backendrediscachingperformancedistributed-systems
Cache Stampede: chống sụp database khi Redis hết hạn

Cache TTL hết đúng lúc traffic peak, hàng nghìn request cùng bắn xuống DB và sập nguyên hệ thống. Bài này mổ xẻ cache stampede và ba cách xử lý đã dùng thật: single-flight lock, early refresh (XFetch), và probabilistic expiration — kèm code Python.

backendrealtimefastapihttparchitecture
Server-Sent Events vs WebSocket: khi nào dùng cái nào

WebSocket không phải lúc nào cũng là câu trả lời đúng cho realtime. So sánh SSE và WebSocket qua các use case thực tế — từ LLM streaming, notifications, đến chat hai chiều — kèm ví dụ FastAPI.

backendapi-designpostgresqlresiliencedesign-pattern
Idempotency Key: thiết kế API không ngại retry

Vì sao retry có thể làm mất tiền của khách hàng, và Idempotency Key giải quyết vấn đề trùng lặp request như thế nào — kèm triển khai thực tế với FastAPI và PostgreSQL.

backendmicroservicespostgresqldesign-patternevent-driven
Outbox Pattern: đảm bảo consistency giữa database và message broker

Tại sao publish event sau khi commit DB lại gây mất event, và Outbox Pattern giải quyết vấn đề này như thế nào — kèm triển khai thực tế với PostgreSQL, FastAPI và một worker đơn giản.

backendmicroservicesresiliencedesign-pattern
Retry và Circuit Breaker: xử lý lỗi tạm thời trong hệ thống phân tán

Chia sẻ cách triển khai retry pattern và circuit breaker để hệ thống phân tán chịu lỗi tốt hơn — từ exponential backoff, jitter đến state machine, kèm code thực tế với Python và TypeScript.

aideveloper-toolsopen-sourceproductivity
Craft Agents: giao diện agent mã nguồn mở mà developer nên thử

Giới thiệu Craft Agents — ứng dụng desktop mã nguồn mở biến AI agent thành đồng đội thực sự với session như document, kết nối mọi API, và workflow linh hoạt cho developer.

aideveloper-toolsopen-sourceproductivity
CMAS: quản lý nhiều tài khoản Claude Code trên một máy — không cần login lại

Giới thiệu CMAS (Claude Multi Account Switcher) — ứng dụng desktop giúp chuyển đổi nhanh giữa nhiều tài khoản Claude Code, mở VSCode isolated sessions, và theo dõi usage real-time.

databasepostgresqldevopsbackendbest-practices
Database migration không downtime: expand-contract pattern và bài học từ production

Chia sẻ cách chạy database migration an toàn trên production mà không cần maintenance window — từ expand-contract pattern, backward-compatible changes đến rollback strategy với Alembic và PostgreSQL.

laravelphpaibackend
Laravel 13: AI SDK, PHP Attributes và những thay đổi đáng chú ý

Tổng hợp những tính năng mới trong Laravel 13 — từ AI SDK first-party, PHP attributes cho Eloquent, vector search với pgvector, đến queue routing và upgrade guide thực tế.

backenddevopsobservabilitybest-practices
Structured logging: debug production hiệu quả mà không cần SSH

Chia sẻ cách chuyển từ console.log/print sang structured logging — JSON logs, correlation ID, log levels, và cách tận dụng chúng để debug production nhanh hơn 10x mà không cần SSH vào server.

backendredissecurityapiperformance
Rate Limiting API: bảo vệ backend khỏi bị quá tải với Redis

Chia sẻ cách triển khai rate limiting thực tế cho API — từ thuật toán sliding window, token bucket đến implementation với Redis và FastAPI, kèm những bài học từ production.

awsroute53cloudfrontwafssldevopsecs
Deploy Nuxt.js + FastAPI lên AWS ECS (Phần 2) — Route 53, CloudFront, SSL và WAF

Phần 2: Hoàn thiện hệ thống production-ready với Route 53 (DNS), ACM (SSL miễn phí), CloudFront (CDN), WAF (tường lửa), auto-scaling và monitoring. Từ ALB domain xấu xí đến website chạy HTTPS với domain riêng.

awsecsnuxtjsfastapigithub-actionsdevopsdocker
Deploy Nuxt.js + FastAPI lên AWS ECS (Phần 1) — Dockerize, ECR, ECS Fargate và CI/CD

Hướng dẫn thực tế triển khai hệ thống full-stack Nuxt.js + FastAPI lên AWS ECS Fargate. Phần 1: Dockerize services, push image lên ECR, setup ECS cluster, và CI/CD tự động bằng GitHub Actions.

gitproductivitydeveloper-tools
Git Worktree: Làm việc nhiều branch cùng lúc mà không cần stash

Hướng dẫn thực tế sử dụng git worktree để checkout nhiều branch đồng thời, review PR nhanh hơn, và xử lý hotfix mà không mất context đang làm dở.

aisecuritydeveloper-toolsbest-practices
Bảo mật AI coding agent: tránh prompt injection, lộ secrets và cấp quyền quá tay

Chia sẻ 6 nguyên tắc thực tế để dùng AI coding agent an toàn hơn trong team dev — từ giới hạn quyền, bảo vệ secrets, đến cách giảm rủi ro prompt injection và supply-chain.

github-actionsci-cddevopsautomation
GitHub Actions CI/CD: Tự động hóa từ test đến deploy

Hướng dẫn thiết lập pipeline CI/CD hoàn chỉnh với GitHub Actions — từ chạy test, build Docker image, đến deploy tự động lên VPS. Kèm tips tối ưu thời gian build và bảo mật secrets.

postgresqldatabaseperformancebackend
Tối ưu PostgreSQL: Index, Query Plan và những bài học từ production

Chia sẻ kinh nghiệm thực tế tối ưu PostgreSQL — từ cách đọc EXPLAIN ANALYZE, chọn đúng loại index, đến những sai lầm phổ biến mà developer hay mắc phải.

aiautomationdeveloper-toolsproductivity
AI Agent cho Developer: Từ assistant đến đồng đội thực sự

Hướng dẫn thực tế cách tận dụng AI agent, sub-agent, skills, hooks và MCP để xây dựng workflow tự động hóa cho developer — không phải lý thuyết suông.

dockerdevopsperformance
Tối ưu Docker image: Từ 1.2GB xuống 80MB với multi-stage builds

Hướng dẫn thực tế giảm kích thước Docker image bằng multi-stage builds, kèm tips bảo mật container và tối ưu build time cho production.

securitynpmsupply-chain
Axios bị tấn công supply chain: tài khoản maintainer bị chiếm, RAT được cài vào máy dev

Phân tích chi tiết vụ tấn công supply chain vào Axios — package npm 100 triệu lượt tải/tuần. Điều gì đã xảy ra, cách phát hiện và bài học rút ra.

vue.jsnuxt.jsfrontend
Tại sao tôi chọn Vue.js/Nuxt.js thay vì React hay Angular

Sau 8 năm làm việc, tôi đã thử cả 3 framework phổ biến nhất. Đây là lý do tôi gắn bó với Vue.js và Nuxt.js cho các dự án của mình.

tản mạn
Xin chào thế giới!

Bài viết đầu tiên trên blog cá nhân hoatq.dev — nơi mình chia sẻ về lập trình, công nghệ và cuộc sống.

astroweb development
Tại sao mình chọn Astro cho blog cá nhân

So sánh các framework phổ biến và lý do mình chọn Astro để xây dựng blog cá nhân — từ hiệu năng, DX đến hệ sinh thái.

productivitycareer
5 thói quen giúp developer làm việc hiệu quả hơn

Những thói quen đơn giản nhưng hiệu quả mà mình đã áp dụng để cải thiện năng suất và chất lượng công việc.

hoatq@dev : ~/blog $