- Knowledge
- technology
- OOP
- Tips
- Programming
- Tips
- Tutorial
- SEO
- Ranking
- Knowledge
- Special Day
- Seo
- Bug
- Data science
- Seo
- artificial intelligence
- Machine Learning
- Robotics
- happyNewYear2021
- newYearEve
- 2021
- Automation
- Smart Home
- Career
- Best Practices
- Git
- Logging
- Web Fundamentals
- DNS
- HTTPS
- Performance
- AI Tools
- ChatGPT
- Claude
- Gemini
- Laravel
- Eloquent
- MySQL
- HTTPS
- TLS
- Web Security
- Certificates
- Developer Life
- Debugging
- Docker
- DevOps
- Transactions
- Queues
- LLMs
- AI
- AI Coding
- Developer Tools
- React Native
- Expo
- Kate PMS
- Mobile Apps
- Laravel
- Authentication
- Sanctum
- Cookies
- API Design
- Payments
- Idempotency
- DeepSeek
- Open Source AI
- LLMs
- AI News
- Git
- Version Control
- AI Coding
- Prompting
- PHP
- Checklist
- MCP
- AI Agents
- OpenAI
- Architecture
- Microservices
- Modular Monolith
- Estimation
- Developer Life
- Project Planning
- Humour
- OAuth
- OpenID Connect
- Authentication
- Embeddings
- Vector Search
- RAG
- pgvector
- OpenAI
- GPT-4.1
- Codex CLI
- Events
- Testing
- Clean Code
- Maintainability
- Code Review
- Webhooks
- API
- Security
- Claude Code
- Workflow
- AI
- LLM
- Prompt Injection
- Mobile
- React
- Networking
- TCP
- UDP
- HTTP/3
- CLAUDE.md
- AWS
- Cloud Security
- Backups
- PHPUnit
- Software Engineering
- Leadership
- Communication
- RAG
- Embeddings
- AI Engineering
- IT Infrastructure
- Networking
- Access Control
- CI/CD
- GitHub Actions
- Gemini CLI
- Claude Code
- JavaScript
- Async/Await
- Node.js
- Promises
- Security
- Cryptography
- Passwords
- MySQL
- Database
- Vibe Coding
- Software Quality
- DNS
- Code Reading
- Onboarding
- Productivity
- Background Jobs
- Developer Humour
- Estimates
- Dev Life
- JWT
- o3-mini
- DeepSeek R1
- Rate Limiting
- Kate PMS
- E-Signing
- Audit Trail
- REST
- GraphQL
- API Design
- Laravel 12
- Upgrade Guide
- Open Source
- Self-Hosting
- Task Scheduling
- Cron
- Secrets
- CORS
- PHP
- PHP-FPM
- OPcache
- GitHub Copilot
- Software Architecture
- Engineering
- TypeScript
- JavaScript
- Type Safety
- AI Security
- React Native
- Product Design
- AI Agents
- Kiro
- Queues
- Redis
- RabbitMQ
- AWS SQS
- Nginx
- Apache
- GPT-5
- gpt-oss
- Clean Code
- Architecture
- Naming
- Documentation
- Career
- ADR
- Teamwork
- Supply Chain
- Kate HRM
- HR Software
- Permissions
- System Design
- Pagination
- SSH
- Linux
- Big O
- Databases
- Laravel Boost
- MCP
- Developer Skills
- Validation
- Databases
- Indexes
- Code Quality
- Deployment
- Developer Humour
- Feature Flags
- Code Review
- Pull Requests
- Docker
- Cursor
- Authorization
- RBAC
- Gemini
- Long Context
- PHP 8.4
- Caching
- Dependency Injection
- Web Performance
- Browser
- CSS
- Database
- Migrations
- ChatGPT
- AI for Developers
- Monitoring
- On-Call
- REST
- Backend
- SQL
- NoSQL
- Database Design
- Coding Agents
- Claude 4
- API Resources
- REST API
- Load Balancing
- Scaling
- AWS
- AI Tools
- Claude
- Sora 2
- CTE
- 2FA
- TOTP
- Programming Languages
- Prompts
- Developer Workflow
- API Gateway
- APIs
- Passport
- API Auth
- Learning
- Burnout
- Developer Growth
- Web Development
- SEO
- Kate Mall
- ChatGPT Atlas
- Agent Skills
- Middleware
- Laravel 12
- Collections
- Context Window
- Monitoring
- Commit Messages
- Self Review
- Growth
- Regex
- Programming Basics
- Text Processing
- Database Design
- Normalization
- Linux
- Server Security
- Linux Foundation
- Open Standards
- Legacy Code
- Documentation
- AI Workflow
- File Uploads
- Test Data
- Hashing
- Performance
- Caching
- Enums
- Scope Creep
- Estimation
- Codex
- Gemini CLI
- Timezones
- Carbon
- Bugs
- PHP 8.5
- Gemini 3
- GPT-5.1
- Data Integrity
- Event Loop
- Async
- Opus 4.5
- AI Models
- React
- Forms
- Frontend
- Backups
- AI Images
- DALL-E
- Midjourney
- Race Conditions
- Concurrency
- Legacy Code
- Refactoring
- Senior Engineer
- Scope
- LLM
- CDN
- Web
- Sub-Agents
- Soft Deletes
- Audit Log
- Concurrency
- AI Learning
- NestJS
- AI Evals
- Policies
- SPF DKIM DMARC
- Unicode
- UTF-8
- Knowledge Graph
- Value Objects
- Technical Debt
- Feature Flags
- Laravel Pennant
- Deployment
- Copilot
- Composer
- Dependencies
- Artisan
- Automation
- AWS S3
- Object Storage
- Cloud
- Small Language Models
- Ollama
- Production
- Sessions
- HTTP
- Mentoring
- SQL
- Virtual Machines
- Web Development
- HTTP/2
- QUIC
- Web Performance
- AI Integration
- LLM API
- SOLID
- OOP
- Hosting
- Serverless
- Merge Conflicts
- Temperature
- AI Development
- Reverse Proxy
- Nginx
- Infrastructure
- Verification
- Passkeys
- WebAuthn
- Teams
- Communication
- Stakeholders
- Monorepo
- CI/CD
- Versioning
- JSON Schema
- Livewire
- Inertia
- Meetings
- Distributed Systems
- Privacy
- Full-Stack
- T-Shaped Skills
- Money
- Notifications
- Web Security
- HTTP Headers
- CSP
- Function Calling
- Load Testing
- k6
- Data Extraction
- Debugging
- WebSockets
- SSE
- Real-Time
- Laravel Reverb
- Infrastructure as Code
- Terraform
- Side Projects
- Laravel Pint
- OpenAPI
- Swagger
- UX
- Multimodal
- Jest
- Pair Programming
- APIs
- Rate Limiting
- Resilience
- Dev Humour
- Design Tokens
- JWT
- API Keys
- Sessions
- PHPStan
- Rector
- Incidents
- Reporting
- Dashboards
- Zero Trust
- IAM
- Search
- Laravel Scout
- Junior Developers
- Mentoring
- Images
- WebP
- AVIF
- Bug Reports
- Let's Encrypt
- Design Docs
- Software Design
- Observers
- Replication
- Accountability
- Data Structures
- Reliability
- LLM Memory
- Error Handling
- Payments
- Payment Gateway
- Webhooks
- PCI DSS
- Observability
- OpenTelemetry
- Personal Brand
- Writing
- Conventions
- Dates
- Scheduling
- Disaster Recovery
- Compression
- Brotli
- Deadlines
- Developer Habits
- State Machines
- Tech Roles
- UUID
- ULID
- Horizon
- Planning
- Engineering Culture
- Ownership
- Soft Skills
- Socialite
- Cost Control
- Collations
- Unicode
- Octane
- PostgreSQL
It Works on My Machine: A Field Guide to the Developer's Favourite Sentence
About Post
Every developer has said it. Most of us have said it with a straight face, in a meeting, while someone shared a screen showing the exact opposite.
"It works on my machine."
It's the developer's favourite sentence because it's always true. That's the problem. It's true, and it's useless, because your machine is the one place nobody else will ever run your code. So here's a field guide to the usual suspects behind it, and what actually makes them go away.
A field guide to the usual suspects
When "works for me" meets "broken on the server", the cause is almost always one of these. I've met every one of them more than once.
The Case-Sensitive Ghost
❌ Your code does require 'Helpers/StringHelper.php'. The file on disk is helpers/StringHelper.php.
On Windows and on a default macOS setup, the file system doesn't care about case, so it loads fine. Linux cares a lot. Same for class names that don't match file names exactly: Composer's autoloader on Linux will simply not find App\Services\PdfService in PDFService.php. Bonus round: Git on a case-insensitive machine may not even notice you renamed a file from pdfService.php to PdfService.php.
The Version Shapeshifter
❌ You run PHP 8.3 locally. The server runs 8.1. You used a typed class constant, the server has a different opinion about it.
The same story plays out with Node versions, MySQL vs MariaDB, and that PHP extension (intl, gd, imagick) that you installed two years ago and forgot about. Your machine has it, the fresh server doesn't.
The Phantom .env
❌ You added PAYMENT_WEBHOOK_SECRET to your local .env. You did not add it anywhere else, because .env isn't committed (correctly).
Laravel has a special twist here: once you run php artisan config:cache, the .env file is no longer loaded, and env() calls outside your config files return null. Works locally without the cache, breaks on the server with it. Always read env values in config/*.php and use config() everywhere else.
The Time Traveller
❌ Your laptop is in Doha, the server is in UTC, and a report that shows "today's payments" is suddenly missing the first few hours of the day. Or including the last few of yesterday.
Time zones break things quietly, often only for some records and only at certain hours, which makes them a joy to debug. Store in UTC, convert for display, and set the app timezone explicitly instead of trusting the machine.
The Dependency Drifter
❌ Someone ran composer update instead of composer install on the server, and a package you depend on moved a minor version.
The lock file exists so every machine installs the exact same versions. Commit it, and deploy with install, never update.
The Permission Gremlin
❌ Locally, you're the owner of every file. On the server, the web server user can't write to storage/, so logs, cache and uploads fail. Sometimes it can't write the log that would tell you it can't write.
The Leftover Cache
❌ The bug is fixed. The server is still serving the old routes, old config or old compiled views. Or the browser is serving the old JavaScript bundle. "Works on my machine" sometimes means "my machine cleared its cache and yours didn't".
What actually fixes it
The real cure isn't being more careful. It's making "my machine" and "the server" the same thing, as much as you can.
✅ Use Docker for local development. Same PHP version, same extensions, same database engine, and a Linux file system, so the Case-Sensitive Ghost shows up on your laptop instead of in production. Laravel Sail gives you a ready-made setup if you don't want to write your own.
✅ Pin your versions. Set the PHP version in composer.json ("php": "^8.2") and commit composer.lock and package-lock.json. Add an .nvmrc for Node.
✅ Keep .env.example honest. Every new variable goes into it in the same pull request, with a placeholder value. Code review should reject a new config() key without one.
✅ Run CI on the same stack as production. If your pipeline runs tests on Linux with the production PHP version, half of these suspects are caught before anyone says the sentence.
✅ Make deploys scripted, not remembered. composer install --no-dev, migrations, config:cache, route:cache, queue restart: in a script, in the same order, every time.
✅ Be explicit about time. Set the timezone in config, store timestamps in UTC.
The parity rule: every difference between your machine and production is a bug that hasn't happened yet. You don't need to remove all of them, but you should know which ones you're living with.
A better sentence
"It works on my machine" closes a conversation. The better version opens one: "It works on my machine, so the difference is in the environment. Let's compare versions, config and data."
Same humility, but now it's the first step of debugging instead of the last line of defence.
Which suspect has bitten you hardest? My money's on the Case-Sensitive Ghost, but I'd love to hear the strange ones.

Be first to comment it...