Getting Of Mercy Falls 4 Running Without Losing Your Mind
I spent three solid days last month trying to get this working on my dev machine. It turns out the documentation skips over a few things that really matter once you hit production. Here is what actually happened and how I fixed it. The installer pulls dependencies from a few different registries, and at least one of them changed its API endpoint mid-release. If you are running npm install and seeing a 404 on a package called @mercy/core-lib, do not panic. The fix is to pin that dependency to version 2.1.3 in your package.json before running the install. I tried upgrading to the latest and it broke the auth flow entirely. Once the packages resolve, the config file lives at .mercy/config.yaml by default. The template they ship with is mostly useless for anything beyond a local test. You need to adjust the redis.connection_string and the worker.thread_pool size. I started with the default of 4 threads and hit a wall where jobs were queuing faster than they were being processed. Bumping it to 16 and setting max-age to 3600 on the job cache solved the backlog. That tradeoff is memory usage though, so keep an eye on your container limits.
How the Pipeline Actually Works
Beginners assume the pipeline is a simple linear chain. It is not. The framework uses a fan-out pattern for the transformation stage, which means each input item gets duplicated across four worker nodes simultaneously. This sounds fast, and it is, until you hit items larger than about 50 megabytes. I ran a batch of asset uploads last Tuesday and watched six workers crash from OOM errors because the duplication multiplied the memory footprint past what the containers could handle. The workaround is to set the fan_out.limit parameter in your config to something reasonable like 20480 kilobytes per item. Items over that size route through a separate serial queue instead. It is slower but stable. Nobody mentions this in the docs because the maintainers seem to assume everyone is running on beefy infrastructure. I was not. Another thing nobody tells you: the retry logic uses exponential backoff capped at 300 seconds, but only if you enable the dead_letter_queue. Without it, failed jobs retry four times and then disappear. I lost an entire batch of transaction records this way because I forgot to configure the DLQ endpoint. Took me two days to reconstruct the data from backups. Set the dead_letter_queue to true and point it at a separate storage bucket. It costs you a bit more in ops overhead but it saves you from losing data when edge cases hit.
Authentication and Deployment Realities
The OAuth flow in Of Mercy Falls 4 defaults to code exchange mode, which works fine in development. In production, you should switch to the client_credentials grant type. The token refresh mechanism in code exchange mode has a known race condition where concurrent requests can invalidate each other's tokens. I discovered this when my staging environment started returning 401 errors at random intervals during load testing. Switching to client_credentials stopped the issue immediately. For deployment, the framework ships with a Dockerfile that assumes you have CUDA installed on the host. If you are running this on a CPU-only environment like I am, you need to use the -cpu variant of the base image and set the device parameter to cpu in your config. Otherwise the framework will try to initialize a GPU backend that does not exist and the worker will crash on startup. This has been an open issue on their GitHub for about eight months and still no fix. Use the CPU image and move on.
Get the Full Details

Performance Tuning That Actually Matters
The default garbage collection settings are aggressive enough to cause latency spikes during peak traffic. I noticed request times jumping from around 120 milliseconds to over 2 seconds every few minutes during heavy loads. The GC pause logs confirmed what was happening. Switching to the G1GC collector and setting the heap size to at least 4 gigabytes brought response times back down to the 130 millisecond range consistently. If you are doing large-scale data processing, disable the built-in compression middleware and handle compression at the reverse proxy layer instead. The framework's compressor runs synchronously and blocks worker threads during the encode pass. Running gzip at the nginx level before requests even hit your app shaved about 40 percent off my average response time on the heavy endpoints. The monitoring dashboard is functional but the event log format is not structured. Parsing it for alerts requires a custom script. I wrote a simple log rotation script that filters for ERROR and WARN level entries and ships them to a centralized logging service. Takes about an hour to set up and it has saved me from missing critical failures multiple times since. The framework does not do this automatically and you will regret that when something breaks at 3 AM.