The support ticket arrived at 9:42 AM. A JOIN without an index had stalled the checkout pipeline for six minutes. Nobody saw it in code review because nobody read the query carefully. AI review tools can help, but most teams assume free tiers are too weak or too limited. This guide shows you a different path: a self-hosted SQL review bot running on free models and a free server, scheduled to scan every merged query before it reaches production.
Disclosure: This article was prepared as part of MonkeyCode's product outreach. MonkeyCode is an open-source assistant that offers free models and a free server option. You can deploy it yourself and point it at your repository. The setup below uses no paid resources, and the same workflow works with any OpenAI-compatible endpoint.
Why a Nightly Review Bot Beats a Pre-Commit Hook
Pre-commit hooks interrupt developers. They create friction, prompt rework, and get disabled after the third false positive. A nightly bot runs after everyone goes home. It scans the queries merged during the day, flags risky patterns, and posts a report to a channel or file. No one is blocked. The next morning, developers see a list of concrete issues with suggested fixes.
The bot does not replace human reviewers. It gives them a head start. If it catches one missing WHERE condition before the data team does, it has paid for itself.
Step 1: Deploy the Free Server
MonkeyCode's free server option gives you a lightweight endpoint for model requests. You do not need a GPU or a cluster. A small virtual machine with 2 GB of RAM is enough for a nightly batch job. Install Docker, pull the MonkeyCode image, and start the container with a single command:
docker run -d -p 8080:8080 --name monkeycode-server monkeycode/server:latest
If you prefer Kubernetes, a minimal deployment manifest works too. The endpoint exposes an OpenAI-compatible API at http://localhost:8080/v1. Keep this server private. It is meant for your own automation, not for public traffic.
Step 2: Configure the Free Models
MonkeyCode routes requests to a free model by default when you use the free tier. You do not need to choose a model name or manage API keys. The client library picks the right model for the task. If you want to override the model for a specific job, you can set it in the request body:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8080/v1",
api_key="any-value", # the local server ignores it
)
response = client.responses.create(
model="free-model", # default free model
input="Review this SQL query. Identify production risks only."
)
print(response.output_text)
The free models handle moderate-length SQL and schema context without issue. They are not the strongest models available, but they are strong enough for pattern-based review, which is exactly what this bot needs.
Step 3: Write the Review Script
Create a script that collects queries from your recent commits and sends each one to the local server. Use git log to get the changed files, then extract SELECT, UPDATE, DELETE, and INSERT statements with a simple parser. The script below shows the core loop in pseudocode:
import subprocess
import re
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/v1", api_key="x")
# Get SQL statements merged today
changed_files = subprocess.run(
["git", "log", "--since=midnight", "--name-only", "--pretty=format:"],
capture_output=True, text=True
).stdout.splitlines()
for path in set(changed_files):
if not path.endswith(".sql"):
continue
content = open(path).read()
statements = re.findall(r"(SELECT.*?;|UPDATE.*?;|DELETE.*?;)", content, re.S)
for sql in statements:
prompt = f"""
Given the schema context below, review this SQL statement.
Schema context: assume standard e-commerce tables.
SQL: {sql}
List only production risks: missing filters, missing limits, inefficient joins.
If none, say 'No issues'.
"""
response = client.responses.create(model="free-model", input=prompt)
print(f"Query: {sql[:80]}...\nReview: {response.output_text}\n---")
This is a starting point, not a production parser. Use your own SQL parser if you need accuracy. The script demonstrates the flow.
Step 4: Schedule the Nightly Run
Put the script in a CI job or a cron job. A simple cron entry on the server runs it every morning at 2 AM:
0 2 * * * cd /opt/sql-review && ./review.py > report.txt
Or use GitHub Actions with a schedule trigger:
name: nightly-sql-review
on:
schedule:
- cron: '0 2 * * *'
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pip install openai
- run: python review.py
The report file or action log becomes the morning digest for your team.
Step 5: Evaluate the Bot with a Decision Table
Before you trust the bot, test it on a labeled dataset. Use ten queries with known problems. Record whether the free model catches each issue. A simple decision table helps you set expectations:
| Issue type | Free model expected behavior | Action if missed |
|---|---|---|
Missing WHERE on a large table |
High catch rate | Rely on your QA environment |
Missing LIMIT on a heavy query |
Medium catch rate | Add a linter rule |
Non‑sargable WHERE clause |
Low catch rate | Teach prompt with examples |
Wrong JOIN type |
Very low catch rate | Human review stays mandatory |
| Correct query flagged as risky | False positive | Tune prompt or ignore first time |
Build your own table with your data. The bot is a pre-filter, not a gatekeeper.
Who Should Not Use This Approach
If your team ships hundreds of SQL files per day, a nightly bot may produce too many false positives. If your queries run against regulated data and require audit trails, you need more than a free model can guarantee. If you have no one to read the morning report, the bot becomes noise.
For most small and medium teams, however, the trade-off is clear. A free server and free models catch the careless mistakes that humans inevitably make at 4 PM on a Friday.
Your Turn: Run the Bot on One Query Tonight
Take the slowest query from your last incident report. Put it in the review script, start a free server, and see what the free models say. The result will not be perfect, but it will be honest. If it catches even one real risk, you have just upgraded your review process without spending a penny.
Try MonkeyCode's free models and free server for your next SQL review experiment. The code in this article runs with minimal changes, and the only thing you lose by waiting is the next missed WHERE clause.
Top comments (0)