Skip to content

Performance & critical fixes: Redis, memory, SQL, indexes, CI gate#106

Merged
frogr merged 1 commit intomainfrom
hermes/performance-fixes
Mar 17, 2026
Merged

Performance & critical fixes: Redis, memory, SQL, indexes, CI gate#106
frogr merged 1 commit intomainfrom
hermes/performance-fixes

Conversation

@frogr
Copy link
Copy Markdown
Owner

@frogr frogr commented Mar 17, 2026

What

Comprehensive performance and safety fixes from the codebase audit. @frogr

Critical Fixes

  • 🔴 Deploy gate — Deploys now require all CI jobs to pass first. Moved deploy job into ci.yml with needs: [scan_ruby, scan_js, lint, test]. Deleted standalone deploy.yml.
  • 🔴 Redis connection leakGpuJob was creating a new Redis.new() on every call. Now uses a shared memoized connection.
  • 🔴 Memory bombtts_batches#download_all and stems#download_all loaded ALL base64 audio into memory for zip creation. Refactored to use temp files and find_each for streaming.

Performance Fixes

  • SQL sort — Replaced Ruby sort_by with SQL ORDER BY COALESCE() in blog controllers
  • Missing indexes — Added indexes on images.published, images.position, review_sections.status, reviews.pr_url
  • Counter cache — Added story_paragraphs_count to stories (eliminates 2 COUNT queries per page load)
  • Bulk insert — TTS batch creation uses insert_all! instead of N individual inserts
  • Race condition — Invoice number generation now uses pg_advisory_lock to prevent duplicates
  • N+1 protection — Added Client.with_invoice_totals for efficient list queries

Infrastructure

  • Pinned Postgres 16 and Redis 7 in CI (were unpinned latest)

Verified

  • bundle exec rubocop — 213 files, 0 offenses
  • bin/rails test — 109 tests, 0 failures, 0 errors

Files changed (14)

M  .github/workflows/ci.yml
D  .github/workflows/deploy.yml
M  app/controllers/admin/blog_posts_controller.rb
M  app/controllers/blog_controller.rb
M  app/controllers/stems_controller.rb
M  app/controllers/tts_batches_controller.rb
M  app/jobs/gpu_job.rb
M  app/models/client.rb
M  app/models/invoice.rb
M  app/models/story.rb
M  app/models/story_paragraph.rb
A  db/migrate/20260317000001_add_missing_indexes.rb
A  db/migrate/20260317000002_add_story_paragraphs_count_to_stories.rb
M  db/schema.rb

… gate

Critical:
- Gate deploys on CI passing (moved deploy into ci.yml with needs)
- Fix Redis connection leak in GpuJob (shared memoized connection)
- Stream zip builds for TTS batch & stems downloads (no more memory bomb)

Performance:
- Replace Ruby sort_by with SQL ORDER BY in blog controllers
- Add missing DB indexes (images, review_sections, reviews)
- Add counter_cache for story paragraphs
- Bulk insert for TTS batch items (insert_all vs N inserts)
- Advisory lock for invoice number generation (race condition)
- N+1 protection: Client.with_invoice_totals class method

Infrastructure:
- Pin Postgres 16 and Redis 7 in CI
- Delete standalone deploy.yml (consolidated into ci.yml)

109 tests, 0 failures. Rubocop clean.
@frogr frogr merged commit bd84286 into main Mar 17, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant