How RektRadar works under the hood: 14 services, 3 Ethereum nodes, hexagonal architecture

Architecture writeup of RektRadar: 14 microservices across 3 Ethereum nodes (1 archive + 2 mempool watchers), hexagonal ports & adapters, ~200ms parallel detection pipeline.

A few people asked me what’s actually under the hood of RektRadar. Here’s the full writeup. No black box, no marketing fluff. Just the architecture diagram of how a scan goes from pasting a contract address to seeing a risk score in ~200ms.

RektRadar global architecture diagram. Three Ethereum nodes (eth1 on Hetzner with full archive node, eth2 and eth3 on OVH dedicated to mempool watching) connected via WireGuard mesh. Eth1 hosts 12 services including rektradar-app gateway, log-ui admin, contract-analyzer, mempool-watcher, factory-watcher, token-forensics, global-analytics, ci-monitor, recap-service, network-ui, contract-maker, remediation-agent, plus PostgreSQL via PgBouncer, Redis, Unleash feature flags, OpenSearch and Prometheus monitoring. Eth2 hosts graph-crawler with its own Redis. Eth3 hosts scoring-engine with its own Redis. An nginx gateway VPS on the edge handles TLS, oauth2-proxy, and routes traffic to the static Astro site rektradar.io and the Vue SPA app.rektradar.io.

The 4-layer setup

Layer 1. 3 Ethereum nodes

  • eth1 (Hetzner, Germany): full archive node. Nethermind 1.36 + Lighthouse 8.1. This is where the bulk of services live.
  • eth2 / eth3 (OVH, France): mempool watchers. Same Nethermind+Lighthouse stack but tuned for pending-tx ingestion. Two of them so we catch rugs in different propagation windows. A sandwich or a sneaky liquidity remove can hit one node a few seconds before the other.
  • All three are bridged by a WireGuard mesh. SSH is closed except on eth1.

Layer 2. 14 microservices

  • Watchers: factory-watcher (Uniswap pool creation), mempool-watcher (pending tx), graph-crawler (deployer chains, eth2), scoring-engine (eth3)
  • Analyzers: contract-analyzer (honeypot simulation), token-forensics (holders + LP), global-analytics
  • Tools: contract-maker, recap-service, ci-monitor, network-ui, remediation-agent
  • UI: log-ui (admin + WebSocket hub), rektradar-app (premium API gateway)

Each service has its own Docker container, its own Ansible role, its own deploy pipeline, and its own health endpoint. They share one PostgreSQL via PgBouncer (1 DB, schema partitioned per service) and a Redis per chain node for cache.

Layer 3. Data plane

  • PostgreSQL 16 + PgBouncer (max 500 client connections, 30 server pool)
  • Redis 7 (one instance per chain node, used for scoring cache + cluster lookups)
  • Unleash (feature flags so I can toggle code paths without redeploy)

Layer 4. Edge

  • nginx gateway VPS (separate from eth1, on OVH). Terminates TLS, routes subdomains, runs oauth2-proxy for admin areas.
  • Fluent Bit on every node, ships nginx + Docker logs to OpenSearch on eth1.
  • Prometheus + Grafana for metrics, AlertManager wired to remediation-agent for auto-healing.

Hexagonal architecture (Ports & Adapters)

Hexagonal architecture diagram. Domain layer in green at the center contains chain-agnostic value objects: RiskAssessment, Trade, Position, NetworkScore, Cluster, BytecodeSignature, EthereumAddress, GraphNode, GraphEdge, with a note about pure logic and 1000+ unit tests. Domain depends on Ports interfaces in orange: BlockchainProvider, DexProtocol, TokenStandard, BlockExplorer, MempoolProvider, BundleProvider, FeeEstimator, EventStore, CacheProvider. Ethereum adapters in red implement the ports: EthersRpcProvider, UniswapDex V2/V3/V4, ERC20Token, EtherscanExplorer, EthMempool, FlashbotsBundle. Solana adapters in dashed gray are listed as roadmap (Phase 3): SolanaRpc, RaydiumDex, SPLToken, HeliusExplorer, GeyserMempool, JitoBundle. A note indicates that L2 EVMs like Arbitrum and Base reuse the Ethereum adapters with a different RPC URL.

Today everything runs on Ethereum. But the long-term goal is multi-chain (Solana first, then Arbitrum / Base / BSC). The reason the codebase is decoupled the way it is:

  • Domain layer is chain-agnostic: RiskAssessment, Trade, Position, NetworkScore, Cluster, BytecodeSignature. Pure logic, ~1000+ unit tests, zero I/O.
  • Ports are interfaces: BlockchainProvider, DexProtocol, TokenStandard, BlockExplorer, MempoolProvider, BundleProvider.
  • Adapters are the concrete implementations. Today there’s an Ethereum adapter for each port (EthersRpcProvider, UniswapDex, ERC20Token, EtherscanExplorer, EthMempool, FlashbotsBundle).

When I add Solana, I don’t touch the domain models. I just write a SolanaRpc adapter, a RaydiumDex adapter, etc. The honeypot detector doesn’t care if the bytecode is EVM or BPF; the network funder analysis doesn’t care if it’s tracing eth_call or simulateTransaction.

L2 EVMs (Arbitrum, Base) are even cheaper. They reuse the Ethereum adapter with a different RPC URL.

6 services have completed this refactor (factory-watcher, graph-crawler, scoring-engine, contract-analyzer, mempool-watcher, log-ui). Mutation tests via Stryker on the domain models, integration tests against a real PostgreSQL.

The detection pipeline

RektRadar detection pipeline diagram. A user request GET /scan/0xabc... hits rektradar-app, the gateway running on eth1, which performs auth check, rate-limit, and cache lookup, then fans out in parallel to four services for about 150ms total. contract-analyzer simulates buy and sell transactions to detect honeypots and liquidity issues. scoring-engine performs a bytecode hash bucket lookup, network funder analysis, and blacklist match. graph-crawler walks back the deployer's history and funder chain. token-forensics analyzes holder distribution and LP lock status. The four results are aggregated into a 0-to-100 risk score with a flag list, cached in Redis with a 60-second TTL, optionally pushed via WebSocket if the score evolves, and returned as a JSON response or a server-side rendered HTML page at /result/{address}, in approximately 200 milliseconds total.

When you scan a contract on the app, here’s what happens behind the scenes:

  1. Request hits rektradar-app (the gateway on eth1). Auth check, rate-limit, cache lookup.
  2. Parallel fan-out to 4 services running concurrently:
  • contract-analyzer simulates a buy then a sell on a forked Ethereum state. If the sell reverts, it’s a honeypot. If the buy succeeds with massive slippage, it’s low-liquidity.
  • scoring-engine does a bytecode hash bucket lookup (clusters of identical contracts indicate a factory). Also looks at the network funder: who paid for the deployer wallet’s gas, and is that funder linked to past rugs.
  • graph-crawler walks back the deployer’s transaction history (previous tokens deployed, prior rugs, age of the wallet).
  • token-forensics checks holder distribution (top-10 concentration), LP lock status, and whether the deployer holds the LP tokens themselves.
  1. Aggregate the results into a 0-to-100 risk score plus flag list (honeypot, low_liquidity, unverified_contract, deployer_history_rugs, etc.).
  2. Cache in Redis (60s TTL) and WebSocket push to any open client viewing that token.
  3. Response: JSON for API consumers, server-side rendered HTML at /result/<addr> for SEO.

Cold scan ~200ms total. Cached ~10ms. Worst case (cold + new bytecode bucket = needs disassembly) ~800ms.

What runs at the SEO and UI edge

  • rektradar.io (landing + blog): Astro static, deployed on Cloudflare Pages. ~52 SEO pages, blog articles, all pre-rendered. Static = fast crawl, free hosting, no SSR overhead. I migrated from a SSR template last month, devnotes here. Big SEO win.
  • app.rektradar.io: Vue 3 SPA + Vuetify, live WebSocket connection to log-ui for streaming events (new pool, new rug detected, score evolution). This part is dynamic by nature.

What’s next on the roadmap

  • Solana adapter. Biggest piece of work. SPL tokens, Raydium / Orca for DEX, Jito for MEV protection, Helius for explorer, Geyser gRPC instead of mempool subscription.
  • L2 EVM. Mostly config: ChainRegistry entry plus Arbiscan/Basescan keys.
  • Multi-snapshot scoring. Store score evolution over time so I can show “this token started at 30 and climbed to 80” graphs.

Try it

Free, no signup: paste any Ethereum contract address on app.rektradar.io, get the risk score and flags. If you find a token I missed flagging correctly, ping me on X or Discord, I want to know.