Building production bots on free APIs sounds cool in theory. In practice, you hit walls immediately. Here are the 5 real errors I encountered while building two Ethereum monitoring bots, and exactly how I fixed them.
Error 1: Alchemy Event Listeners Timeout After 5 Minutes
The Problem:
I started monitoring Aave liquidations using ethers.js event listeners on free-tier Alchemy.
provider.on(filter, (log) => {
console.log("Liquidation detected:", log);
});
Worked perfectly for 5 minutes. Then the WebSocket died. No error message. Just silence. Listener stopped working forever.
Why it happens:
Free-tier Alchemy (and most providers) have timeout limits on WebSocket connections. Idle connections get dropped. No reconnect logic on the free tier.
The Fix:
Stop using event listeners. Use polling instead.
async function pollLiquidations() {
const currentBlock = await provider.getBlockNumber();
const logs = await provider.getLogs({
address: AAVE_LENDING_POOL,
topics: [LIQUIDATION_CALL_TOPIC],
fromBlock: currentBlock - 9,
toBlock: currentBlock
});
logs.forEach(log => handleLiquidation(log));
}
// Poll every 15 minutes
setInterval(pollLiquidations, 15 * 60 * 1000);
The lesson: On free tier, reliability > real-time. Polling every 15 minutes that works beats real-time listeners that disconnect.
Error 2: CoinGecko Rate Limit 429 (Too Many Requests)
The Problem:
I wanted to track 5 tokens: UNI, AAVE, USDC, DAI, USDT.
const tokens = ['UNI', 'AAVE', 'USDC', 'DAI', 'USDT'];
async function getPrices() {
const prices = await Promise.all(
tokens.map(token =>
axios.get(`https://api.coingecko.com/api/v3/simple/price?ids=${token}...`)
)
);
}
// Check every 15 minutes
setInterval(getPrices, 15 * 60 * 1000);
After a day, I got slammed with 429 errors. CoinGecko rate-limited me. Price alerts stopped working.
Why it happens:
Free-tier CoinGecko allows ~5 requests per second, but daily limits kick in after 50 concurrent calls per minute. 5 tokens × 96 checks/day = 480 calls. You hit the limit.
The Fix:
Reduce frequency OR reduce tokens. I chose frequency.
const tokens = ['UNI', 'AAVE']; // 2 tokens only
// Check every 2 hours (not 15 mins)
// 2 tokens × 12 checks/day = 24 calls. Under limit.
setInterval(getPrices, 2 * 60 * 60 * 1000);
Still catches all meaningful moves (5%+ happens in hours, not minutes).
The lesson: APIs are precious on free tier. Reduce scope, not reliability. 2 tokens checked reliably > 5 tokens checked intermittently.
Error 3: Supabase RLS "New Row Violates Row-Level Security Policy"
The Problem:
Bots ran fine for 2 days. Then suddenly:
Supabase error: new row violates row-level security policy for table "price_history"
Both bots stopped writing data. Data collection halted. Silent failure.
Why it happens:
I had Row-Level Security (RLS) enabled but forgot to disable it for anonymous (public) access. When the bots tried to INSERT with anon key, RLS rejected them.
// This would fail
const { error } = await supabase
.from('price_history')
.insert([{ symbol: 'UNI', price: 5.94 }])
The Fix:
Disable RLS on the tables (if you're the only user):
ALTER TABLE price_history DISABLE ROW LEVEL SECURITY;
ALTER TABLE liquidations DISABLE ROW LEVEL SECURITY;
Or enable RLS but create a policy:
CREATE POLICY "Enable insert for all" ON price_history
FOR INSERT WITH CHECK (true);
The lesson: RLS is security theater on hobby projects. Disable it for free tier. Enable it when you have real users.
Error 4: "Cannot Find Module" In Termux File Creation
The Problem:
I created a data analysis script but it wouldn't run:
$ node data-analysis.js
Error: Cannot find module '/data/data/com.termux/files/home/data-analysis.js'
File seemed to exist, but Node couldn't find it. Turned out the file never actually created properly.
Why it happens:
When copying files to Termux , file paths get weird. The tool thinks it created the file, but Termux didn't actually receive it.
The Fix:
Create files directly in Termux using nano:
nano data-analysis.js
Paste content, save with Ctrl+X → Y → Enter.
Verify with:
ls ~/*.js
The lesson: Don't rely on external file creation tools for Termux. Nano is slower but reliable.
Error 5: Can't Exit tmux On Mobile Keyboard
The Problem:
I attach to a tmux session to check bot output:
tmux attach -t price-alert
See the output, want to exit. Try Ctrl+B then D. Nothing happens. Keyboard doesn't register the key combo properly on mobile.
Stuck in the session. No escape.
Why it happens:
Mobile on-screen keyboards don't register modifier key combos well (Ctrl+B, Alt+X, etc). Long-press + tap doesn't work reliably.
The Fix:
Don't attach at all. Use capture-pane instead:
tmux capture-pane -t price-alert -p
Shows last output without entering the session. No exit needed. No stuck state.
For killing a session if you DO get stuck:
# In a new terminal
tmux kill-session -t price-alert
The lesson: Avoid interactive sessions on mobile. Use read-only commands instead.
The Pattern
All 5 errors follow the same theme:
Free tier + unconventional setup (mobile, no servers) = constraints.
The fix isn't "pay more" or "use better tools." It's work within constraints:
- Event listeners die → use polling
- Rate limits hit → reduce scope
- RLS blocks → disable it
- File creation fails → use native tools
- Keyboard combos don't work → avoid them
That's the real lesson. Not the specific fixes, but the mindset: I'm not building for ideal conditions. I'm building for free APIs, free databases, and a phone running Linux.
Ship anyway.
Running on: Termux (Android), free-tier Alchemy, free-tier CoinGecko, Supabase free tier, tmux
Timeline: Sept 1-12, 2026. Two weeks into production.













