When ENV is no longer ENV – Tricks from the runtime environment

ENV

Last week, my old team (all members who used to work on SDK API projects) suddenly reunited… not to reminisce about the old days, but because they were all hitting the same “weird” dotenv bug while deploying a new project with Laravel.

A peculiar situation with Larave

Thành (Back-end Engineer) ran into a bug: the first request could read values via env(), but the second request… just failed.

Hùng (Front-end Engineer) noticed a similar issue after deployment: his config values didn’t match what he had locally.

After some head-scratching and debugging, it turned out both issues were deeply related.

Laravel, dotenv, and the trickery called config:cache

Here’s the root of the problem:

  • Laravel doesn’t recommend calling env() directly in your app logic after the app has booted.
  • In production, Laravel strongly recommends (and practically requires) running php artisan config:cache, which compiles a static config file for faster performance.
  • After running config:cache, direct env() calls won’t work reliably anymore. You might get null or inconsistent results, especially under concurrent requests.

Thành’s bug:
He called env() during runtime, not in the initial config → so on the second request, the value was gone.

Why Laravel behaves this way:
Laravel wants you to freeze all config values at deploy time using config:cache, so the app doesn’t rely on ENV at runtime.

Switching gears to AWS Lambda and NodeJS…

Flashback to a project from a year ago using AWS Lambda (NodeJS). AWS deprecated Node v6 and suggested upgrading to v8. Sounds simple, but after the upgrade, we hit a timezone bug:

We expected it to print in Japan time (JST) → It printed in UTC.

After investigation, here’s what we found:

  • The app used process.env.TZ = ‘Asia/Tokyo’ inside the code – before initializing the app.
  • But this didn’t work anymore.

Turns out, this was a trap:

In NodeJS, once new Date() is called, the timezone is cached based on the TZ environment variable.

In Lambda, AWS might call new Date() before your code runs (e.g., for logging or internal init) → meaning your late-assigned TZ doesn’t work.

Fix: Set TZ directly in Lambda’s environment settings, not in your code.

Key Lessons

No matter what framework you use – Laravel, NodeJS, or anything else – how you handle ENV affects the stability and predictability of your app.

Golden rules:

  • Read ENV variables only once, as early as possible (ideally before the app starts).
  • Never scatter env() calls throughout your code. Centralize them in config files or constants.
  • If your framework supports config caching (like Laravel with config:cache), always use it in production.
  • Avoid using dotenv in production – even the library author says so in the README.

Small things that cause big headaches: options & config

A lot of bugs don’t come from the core logic itself, but rather from not fully understanding the config or simply not reading the documentation carefully enough.

On StackOverflow, you see tons of correct answers that are literally just adding one line of config.

“A friend once told me: seasoned folks really like to dive into the source code of libraries.”

My simple thought is that they just don’t completely trust the ReadMe anymore 😂

One last “Red Flag”…

One day, our project team found a nasty bug: AWS SDK for Greengrass IoT automatically reset the NODE_TLS_REJECT_UNAUTHORIZED variable. So even if we set it to skip TLS checks, it silently reverted.

Lesson: ENV vars aren’t always immutable. Libraries can override them behind your back.

Conclusion

If you’re working in backend, don’t underestimate your environment variables.

Understand your runtime – whether it’s Laravel, NodeJS, or AWS Lambda – because each one handles ENV differently.

ENV isn’t just config. It’s a hidden power that can shape your app’s behavior in surprising ways.

Credit: Ton That Bach (Technical Leader in Mynavi TechTus Vietnam)

case studies

See More Case Studies

Contact us

Partner with Us for Comprehensive IT Solutions

We’re happy to answer any questions you may have and assist you in determining which of our services best meet your needs.

Your benefits:
What’s the next step?
1

We schedule a call at your convenience.

2

We conduct a discovery and consultation meeting.

3

We prepare a proposal based on your needs.

Book a free consultation