Cumhurbaşkanı Erdoğan, 5G İletişim Törenine Katılacak

Cumhurbaşkanı Recep Tayyip Erdoğan, 5G teknolojilerinin tanıtım yapılacağı ‘5G ile İletişimde Güçlü Türkiye Töreni’ne katılacak. Tören, Cumhurbaşkanlığı Külliyesi’nde gerçekleştirilecek ve saat 14.30’da başlayacak. Bu etkinlik, Türkiye’nin iletişim altyapısını güçlendirme ve dijital dönüşüm hedeflerine yönelik önemli bir adım olarak değerlendiriliyor.

Yapay zeka “Suçlu” dedi, hayatı karardı

ABD’nin Tennessee eyaletinde yaşayan 50 yaşındaki Angela Lipps, yapay zeka tabanlı yüz tanıma sisteminin hatalı eşleşmesi sonucu, hiç gitmediği bir eyalette işlenen suçtan dolayı 108 gün boyunca hapis yattı. Mart 2026 itibarıyla hukuk mücadelesi başlatan Lipps’in, emniyet birimlerinin teknolojiye “aşırı güveni” ve “ihmali” nedeniyle evini, işini ve sağlığını kaybettiği ortaya çıktı.

🖥️ Weekend Project: A CLI to Manage Multi-Monitor Layouts on Windows

This weekend I built a small tool to solve a very real (and annoying) problem…

I’ve been working with 4 monitors for a while now. My setup includes an ultrawide monitor as primary when I work, but, when I want play videogames I preffer use a 24″ monitor (when isn’t a simrace game), so, here are two cases were I need change my screens layout.

Every time I move between those setups, I have to manually rearrange monitors in Windows.

Doing that repeatedly? Not fun 😅, some times I do that 3 times peer day 🫠.

🤔 Looking for a solution

I tried to find an existing tool to automate monitor layouts, but nothing quite matched what I needed.

So I decided to build a simple CLI:

👉 wsm — Windows Screen Manager

A lightweight tool to save and restore monitor configurations as profiles.

⚡ What it does

The idea is simple:

  • Save your current monitor layout
  • Store it as a profile (YAML or JSON)
  • Restore it instantly with a command
wsm save work -- save current layout
wsm load game -- load saved layout

If you frequently change your screen layout, this can save you a lot of time.

wsm list
Saved profiles in ~/.wsm-profiles:
  game — 4 monitor(s)
    Display 1: GBT340A                       3440x1440 @ 60Hz  pos (-1515, -1440)  primary: false
    Display 2: BNQ78E7                       1920x1080 @ 60Hz  pos (    0,     0)  primary: true
    Display 3: BNQ78E7                       1920x1080 @ 60Hz  pos (-1928,     0)  primary: false
    Display 5: ACI1643                       1080x1920 @ 60Hz  pos ( 1925,  -916)  primary: false
  work — 4 monitor(s)
    Display 1: GBT340A                       3440x1440 @ 60Hz  pos (    0,     0)  primary: true
    Display 2: BNQ78E7                       1080x1920 @ 60Hz  pos ( 3440,  -562)  primary: false
    Display 3: BNQ78E7                       1920x1080 @ 60Hz  pos (-1920,   350)  primary: false
    Display 5: ACI1643                       1080x1920 @ 60Hz  pos ( 4520,  -552)  primary: false

📦 How it works

Under the hood, the CLI:

  • Reads all active monitors
  • Captures:
  • resolution
  • refresh rate
  • position in virtual desktop
  • primary display
  • orientation
  • Stores everything in ~/.wsm-profiles

Example YAML:

profiles:
  office:
    monitors:
      - device_name: '\.DISPLAY1'
        friendly_name: 'Display 1: GS34WQCA'
        position_x: 0
        position_y: 0
        width: 3440
        height: 1440
        refresh_rate: 144
        bits_per_pel: 32
        orientation: 0
        is_primary: true
      - device_name: '\.DISPLAY2'
        friendly_name: 'Display 2: P2419H'
        position_x: 3440
        position_y: 180
        width: 1920
        height: 1080
        refresh_rate: 60
        bits_per_pel: 32
        orientation: 0
        is_primary: false

🧠 Atomic configuration changes

One important detail: applying layouts is done atomically.

Instead of changing monitors one by one (which can cause flickering or broken states), the tool:

  • stages all changes using Windows APIs
  • commits them in a single operation

This avoids intermediate invalid configurations.

Also:

  • The primary display is always staged first
  • Missing/disconnected monitors are handled gracefully

🧪 Built with AI

I built this using Claude, and had a working version in under an hour.

That said, it wasn’t just “generate and done”:

  • There were bugs
  • Edge cases around Windows APIs
  • Iterations to get things stable

The AI helped a lot, but I still had to guide it and understand what was going on.

📈 Iterating on the idea

The first version was pretty basic:

  • JSON files
  • One file per configuration

Then I improved it:

  • YAML as default (more readable)
  • Profiles instead of separate files
  • Still supports JSON if needed

🎛️ Stream Deck integration

Running commands is fine… but I wanted something faster.

So I built a plugin for the Elgato Stream Deck, this can run anny command on powershell or cmd.

Now I can switch my entire setup with a single button press.

🧠 A reminder about AI

I’ve been in software development for about 10 years.

Back then, the advice was:

“It’s fine to copy from Stack Overflow… but understand what you’re copying.”

That still applies today.

AI is powerful, but:

  • It makes mistakes
  • It hallucinates
  • It doesn’t replace understanding

If something breaks, you still need to know how to fix it.

🚀 Try it out

If you’re on Windows and frequently change your monitor layout, this might be useful:

👉 https://github.com/OsirisFrik/windows-screen-manager

Data-Driven Architecture

1360_LinuxExceptionTwo/image1.png

The layering problem

Applications often have many layers, such as repositories and ORMs, due to patterns like MVVM, MVC, and the Hexagonal architecture. My main argument is that these architectural decisions, while intended for general use, often feel rigid or contextless, especially for microservices or even monorepos. The art of architecture is about composing components into systems, but this process relies heavily on context and appreciation. Patterns exist as recipes for recurring problems, but when applied without context, they can feel forced and less relevant. Examples from books rarely match your real problem, and frameworks can lock you into abstractions that don’t match your needs.

Here’s my thought: let problems find you first. If they don’t, it’s either because they don’t belong or you don’t recognize them. Reading about them isn’t enough. It’s better to try building with these patterns elsewhere—not at work—unless guided by someone more experienced. Sometimes practice is best, or even necessary, when speed matters. Frameworks exist because they embed valid patterns for specific cases. Companies offer ready-made solutions like ORMs, ERPs, or Next.js; you may use them if patterns fit. Otherwise, question and resist the urge to apply patterns by default. Avoid Resume-Driven-Development traps.

Data-Driven Design

While there is literature about high-level architectural design and modules in “The Philosophy of Software Design” that I find interesting, the simplest and most effective driver I’ve found is data itself. My argument leads to a key idea: everything points toward a data-driven approach. Rather than starting with high-level abstractions, focus on your data. Shape your system by following your data and encoding it using clear, simple structures. This approach will usually simplify both design and tool selection, letting your data’s characteristics guide architecture and modeling choices to best suit your use case.

This is DDD at its core, and it also favors deep modules, as the referenced book says. Large modules should fade or be autogenerated. Focus on your domain and API simplicity, which depend on how well you encode data and its relationships. Here, DDD’s data aggregates help: when you need several objects to interact, think of them together as a unit, not just related items. This encourages simple design and cuts down race conditions, as changes to coupled parts remain atomic. Other concepts exist—better explained elsewhere—but everything comes down to business, data, or algorithm invariants. Find these invariants, then encode them. Use an automaton. If you could learn one thing in Computing Science, pick a DFA. It’s a first principle to help avoid over-engineering.

Automata and the Power of Explicit State

Finite Automata excel because they work with data and can process almost any computable input. Bugs often stem from accepting too much or omitting needed data. Protocols frequently use this concept. Though RFCs and implementations differ, starting with a DFA is wise for such problems. It’s the simplest way to define data boundaries and is nearly linear in speed. If your issue is data-related, always think it through with automation first. This clarifies your approach and shows if another data structure is needed. Don’t jump into polished solutions when starting new work, if you can avoid it.

Many think you shouldn’t build from scratch, which makes sense given today’s abundance of libraries. But if data is core to your business, treat it as seriously as outsourcing. Don’t outsource your core. Even without an MBA, I believe in this, and many smarter people agree. Books like Amazon’s “Working Backwards” or Netflix’s “Engineering Culture” strike me as well-meaning novels. Company realities are messier: every company is a ball of controlled technical chaos to keep up with business scale. To fight this, prioritize your principles as a technical lead and let business leaders handle the rest. Simplify early and check complexity with each new code addition.

Object-Oriented Pitfalls and the Relational Model Trap

Object-oriented programming’s downside is its link to the relational model. While not always true, big enterprise problems usually stem from data modeling. Academics start from relational algebra, which differs from category theory. Smalltalk’s background is separate from relational algebra, but it’s misapplied to enterprise systems. Originally, code automated processes, not fixed algorithms—this is a flawed outlook. Treat data as a first-class citizen from the start, not an afterthought. While we write in terms of behavior and output, we shouldn’t shape code solely for data or processes. It’s tricky, but embracing this shift leads to simpler code.

Final recommendations

Below are good starting points for my ideas. I have plenty of reinforcement bias, but I don’t recommend that, or linking to anything that isn’t my interpretation, since people might see things differently. A discussion forum might be better for debate than a blog post. If you’re interested, it’s better to look in books or projects rather than hearing from someone who shares your thoughts—unless it’s just for fun and entertainment, as I do.

Finally, I leave you with some extra advice, from my discussion about the subject with my today’s victim, as lately, ChatGPT or whatever other LLM kind of chat. It turns out that’s the best way to challenge my thoughts nowadays, and it’s worth it for summary or tl;dr sections if you are that kind of guy. But I put it at the end just bc of that. Although I am still looking for perfection on those ideas and principles, if you like, I’m aware that the world is complex enough and you always need to deal with physics one way or another, that means you eventually will face reality and need to talk with external systems and distributed networks, even though you only have a database and OS as a runtime. Because of that, on scale, you will need to think in other layers as well. But that’s the point, if you already have enough layers on top of your system. Why did you shoot yourself in the foot and put more inside your app?

The clean mental model (ChatGPT extracted)

Think in three layers:

  1. Domain (DDD core)
    • Strong invariants
    • Impossible invalid states
    • Explicit transitions
    • “What is allowed?”
  2. Application / workflow
    • Ordering of steps
    • Retries
    • Orchestration
    • “What happens next?”
  3. Infrastructure
    • DBs
    • Queues
    • APIs

Most bugs happen when:

  • Layer 2 logic leaks into layer 1
  • Invariants are not enforced in layer 1

Trying to cross-post here since I always wanted to give back to this community what I had learned from it. Other than that, my Substack looks pretty lonely so far. Check this out in case you found this article interesting (it will be published next week). And this may help me with early feedback to include corrections and examples there.

Crow Docs Evolving: Stability, UX, and a New Community Channel 🚀

Crow Docs Evolving: Stability, UX, and a New Community Channel 🚀
Hi everyone!

I’m dropping by to share a general update on the Crow Docs project. The focus of the latest updates was ensuring a solid foundation, fluid navigation, and—most importantly—opening a direct channel to hear from those using the tool.

For those who aren’t familiar, Crow Docs is a suite of PDF and OCR tools that runs 100% client-side, prioritizing privacy above all else (no server uploads, ever!).

🛠️ What’s New?
Interface Refinement: We’ve implemented UX improvements and optimized loading speeds for a much smoother experience. Less friction, more productivity.

Deep Bug Squashing: We did a thorough “fine-tooth comb” sweep! We fixed instabilities and minor rendering glitches that were popping up in specific browser environments.

Suggestions Box: We now have an official channel! Want a new feature or found something weird? Your feedback now has a dedicated home at the bottom of the page.

Project Support: I’ve added a section for anyone who wants to support the development and help keep the project’s infrastructure standing.

💡 Why the Community Focus?
This project is driven by real-world usage. Adding the Suggestion and Support buttons at the footer was the best way I found to turn Crow Docs into something built by many hands.

🔗 Explore it now:
If you need fast, secure, and privacy-focused PDF tools, take a look:

👉 crowdocs.com.br

What feature would you like to see in a 100% browser-based document tool? Let me know in the comments or use the new suggestion box on the site!

Codacy vs Veracode: Code Quality vs Enterprise AppSec

Codacy screenshot

Quick Verdict

Codacy screenshot
Veracode screenshot

Codacy and Veracode are not in the same product category. Codacy is a developer-oriented code quality platform that includes security scanning as part of a broader code health offering. Veracode is an enterprise application security testing platform built for CISOs, security directors, and AppSec teams. Comparing them directly is like comparing a Swiss Army knife to a professional-grade power tool – one provides versatile coverage across many dimensions, the other provides deep capability in a specific domain.

The fundamental difference: Codacy answers the question “Is our code clean, well-tested, and reasonably secure?” Veracode answers the question “Does our application have exploitable vulnerabilities that could lead to a data breach?” These are related but distinct concerns, and the tools reflect that distinction in every design decision – from pricing ($15/user/month vs. $15,000+/year) to setup time (10 minutes vs. weeks) to target buyer (engineering leads vs. CISOs).

Choose Codacy if: you are a development team that needs a single affordable platform for code quality enforcement, coverage tracking, basic security scanning (SAST, SCA, secrets), and AI-powered code review. You want to ship cleaner code with fewer bugs and reasonable security coverage without enterprise procurement overhead. You value setup simplicity, predictable per-user pricing, and the ability to scan AI-generated code with the free AI Guardrails IDE extension.

Choose Veracode if: you are an enterprise security team that needs deep application security testing – binary SAST, DAST with AI-assisted authentication, SCA with behavioral supply chain analysis, compliance reporting aligned to PCI DSS, HIPAA, FedRAMP, and GDPR, developer security training at scale, and auditor-recognized certification. Your security program has budget, headcount, and compliance mandates that require enterprise-grade tooling.

If your organization needs both code quality and deep security: Use both. Codacy and Veracode have minimal feature overlap, and running them together provides comprehensive coverage. Or pair Codacy with a more affordable security tool like Snyk or Semgrep if Veracode’s pricing exceeds your budget.

At-a-Glance Feature Comparison

Category Codacy Veracode
Primary focus Code quality + basic security Enterprise application security
Target buyer Engineering leads, dev teams CISOs, AppSec teams, compliance officers
SAST approach Source code analysis (embedded engines) Binary-level + source code analysis
SAST languages 49 languages 30+ languages
DAST ZAP-powered (Business plan) AI-assisted auth DAST (dedicated product)
SCA Included in Pro plan Phylum behavioral analysis (dedicated product)
Secrets detection Yes Yes
Container scanning No Yes
IaC scanning Limited Yes
AI code review AI Reviewer (hybrid rule + AI) None (Veracode Fix is remediation only)
AI code governance AI Guardrails (free IDE extension) None
AI remediation AI Reviewer suggestions Veracode Fix (AI-powered)
Code quality analysis Yes – patterns, complexity, duplication No
Code coverage tracking Yes No
Quality gates Customizable thresholds on PRs No (security policy gates only)
Developer training No Security Labs (hands-on training)
Compliance certification No Verified by Veracode
Compliance reporting Basic (OWASP, SANS mapping) Deep (PCI DSS, HIPAA, SOC 2, FedRAMP, GDPR)
Free tier AI Guardrails IDE extension No
Starting paid price $15/user/month (Pro) ~$15,000/year (SAST only)
Setup time Under 10 minutes Weeks to months (enterprise deployment)
Git platforms GitHub, GitLab, Bitbucket GitHub, GitLab, Bitbucket, Azure DevOps
Self-hosted Business plan (premium pricing) Cloud-primary, on-premises available

What Is Codacy?

Codacy is an automated code quality and security platform trusted by over 15,000 organizations and 200,000 developers. Founded as a cloud-native code quality service, Codacy has evolved into a comprehensive developer platform that packages code quality analysis, SAST, SCA, DAST, secrets detection, code coverage tracking, duplication detection, and AI-powered code review into a single product with predictable per-user pricing.

Codacy’s design philosophy centers on developer accessibility. The platform connects to GitHub, GitLab, or Bitbucket and begins scanning pull requests automatically without any CI/CD pipeline configuration. Analysis runs on Codacy’s infrastructure, eliminating the need for build pipeline integration for basic scanning. This pipeline-less approach is the fastest setup experience in the code quality category – most teams go from signup to first analysis results in under 10 minutes.

The platform supports 49 programming languages through a strategy of embedding multiple third-party analysis engines – ESLint, Pylint, PMD, SpotBugs, Bandit, Gosec, and dozens of other language-specific analyzers – rather than building a single proprietary rule engine. This gives Codacy broad language coverage with the analysis depth of each embedded tool.

Codacy’s AI capabilities include three interconnected features. AI Guardrails is a free IDE extension for VS Code, Cursor, and Windsurf that scans code – including AI-generated code – in real time and auto-remediates issues before they are committed. AI Reviewer combines deterministic rule-based analysis with context-aware AI reasoning that draws on changed files, PR descriptions, and linked Jira tickets. AI Risk Hub (Business plan) provides organizational-level visibility into AI code risk.

Pricing is straightforward: the free Developer tier includes AI Guardrails. The Pro plan costs $15/user/month with unlimited scans, repos, and lines of code, and includes SAST, SCA, secrets detection, coverage tracking, duplication detection, and quality gates. The Business plan adds DAST, self-hosted deployment, SSO/SAML, and the AI Risk Hub at custom pricing.

Codacy is a G2 Leader for Static Code Analysis as of 2025, and is positioned as a modern, affordable alternative to heavier platforms like SonarQube for teams that want quality and basic security in a single tool.

What Is Veracode?

Veracode is an enterprise application security testing platform founded in 2006 in Burlington, Massachusetts. Veracode has been a Gartner Magic Quadrant Leader for Application Security Testing for 11 consecutive years – the longest streak of any vendor in the category. The company serves over 2,500 customers globally and has scanned over 37 trillion lines of code.

Veracode’s technical differentiator is binary-level SAST analysis – the ability to scan compiled artifacts (JARs, DLLs, WARs, executables) without requiring access to the original source code. This approach analyzes the actual compiled representation of the application, catching certain vulnerability classes that source-code-only tools may miss while enabling scanning of third-party components, acquired codebases, and legacy applications where source code may be unavailable or lost.

The Veracode platform covers multiple security testing dimensions. Veracode SAST performs binary and source code static analysis across 30+ languages, with Pipeline Scan providing a lightweight CLI for fast CI/CD integration. Veracode DAST tests running web applications with AI-assisted authentication handling that navigates complex login flows automatically. Veracode SCA scans open-source dependencies using Phylum behavioral analysis technology that sandbox-executes packages to detect malicious behavior beyond CVE database matching. Package Firewall blocks malicious packages at the repository level.

Veracode Fix is the AI-powered remediation engine that generates code fix suggestions for identified vulnerabilities, reportedly reducing fix time by up to 92%. Veracode Security Labs provides interactive, hands-on developer security training in containerized lab environments – a unique capability among AppSec platforms. The Verified by Veracode certification program provides third-party attestation that auditors in regulated industries recognize as evidence of a mature security program.

Veracode’s compliance reporting covers PCI DSS, HIPAA, SOC 2, NIST 800-53, FedRAMP, and GDPR. The platform generates audit-ready reports that align with regulatory framework requirements.

Pricing reflects Veracode’s enterprise positioning. SAST alone starts at approximately $15,000-$25,000/year for a single application. The full enterprise platform with SAST, DAST, SCA, Security Labs, and compliance features ranges from $50,000 to $250,000+ annually depending on application count and developer seats.

Feature-by-Feature Breakdown

SAST: Source Analysis vs. Binary Analysis

This is the most fundamental technical difference between the two platforms and reflects their entirely different design philosophies.

Codacy’s SAST performs source-code analysis using embedded third-party engines across 49 languages. When a developer opens a pull request, Codacy runs the relevant analyzers against the changed code and posts inline comments with severity ratings and remediation guidance. The analysis detects common vulnerability patterns – injection flaws, authentication issues, cryptographic weaknesses, insecure data handling – alongside code quality issues. The strength is breadth: 49 languages covered, combined quality and security findings in a single scan, and zero CI/CD configuration required for basic scanning.

The limitation is depth. Codacy’s security analysis depends on the capabilities of the embedded engines rather than a purpose-built security scanning engine. Complex multi-file vulnerability chains – where tainted input enters the application in one method and reaches a dangerous sink several layers deeper – are harder for Codacy to detect compared to dedicated SAST engines.

Veracode’s SAST performs both binary and source-level analysis using a proprietary scanning engine refined over nearly two decades. The binary analysis approach is unique: applications are compiled and the resulting artifacts (JARs, DLLs, WARs) are uploaded to the Veracode cloud for analysis. The scanner examines bytecode, MSIL, and native binaries to detect vulnerabilities in the compiled representation of the code. This catches certain vulnerability classes that source-only tools miss – compiler-introduced issues, runtime behavior patterns visible in bytecode, and vulnerabilities in the interaction between compiled modules.

The critical advantage of binary analysis is scanning without source code. Third-party vendor libraries, acquired codebases during M&A due diligence, legacy applications where build environments no longer exist – Veracode can analyze all of these. No other major SAST vendor provides this capability.

The tradeoffs are speed and source mapping. Binary analysis requires compilation and upload, making the scan cycle slower than source-level analysis. Full platform scans can take hours for large applications. Pipeline Scan mitigates this for CI/CD workflows by providing faster results, but the overall scanning experience is slower than Codacy’s automatic PR-level analysis. Additionally, mapping binary-level findings back to specific source code lines can be less precise than source-level analysis.

Bottom line on SAST: Veracode provides deeper, more mature security-focused SAST with the unique ability to scan compiled artifacts. Codacy provides broader language coverage with combined quality and security analysis at a fraction of the cost. Teams that need enterprise-grade vulnerability detection – especially for compiled or third-party code – need Veracode. Teams that need “good enough” security scanning alongside code quality enforcement will find Codacy sufficient.

SCA: Basic Coverage vs. Behavioral Analysis

Both tools include Software Composition Analysis, but the depth and approach differ substantially.

Codacy’s SCA is included in the Pro plan at $15/user/month. It scans dependency manifests (package.json, requirements.txt, pom.xml, and others) to identify known vulnerabilities in open-source packages, tracks CVEs across the dependency tree, and alerts teams to newly disclosed vulnerabilities. The SCA findings appear alongside code quality and SAST results in the same PR review, providing a unified view of all code health concerns.

Codacy’s SCA is effective for basic dependency vulnerability alerting but does not match the depth of dedicated SCA platforms. It does not include reachability analysis (determining whether vulnerable code paths in dependencies are actually called by your application), behavioral analysis for detecting malicious packages, or automated remediation PR generation.

Veracode’s SCA is a dedicated product with significantly deeper capabilities. The integration of Phylum behavioral analysis technology sets it apart from most SCA tools. Traditional SCA matches package versions against CVE databases. Veracode’s behavioral analysis sandbox-executes packages to detect malicious behavior – data exfiltration, reverse shell establishment, credential theft, and cryptocurrency mining – regardless of whether the package matches a known CVE. This addresses zero-day supply chain attacks that exploit novel techniques undetectable by database-only approaches.

Package Firewall extends this protection proactively by blocking malicious or vulnerable packages at the repository level before they enter your dependency tree. Veracode SCA also includes license compliance checking and SBOM generation in SPDX and CycloneDX formats.

The accessibility gap matters: Codacy includes SCA in a $15/user/month plan. Veracode SCA is a separate product that typically starts at approximately $12,000/year and is most commonly purchased as part of the enterprise platform bundle. For teams that need basic dependency vulnerability alerts, Codacy’s included SCA provides real value without additional cost. For teams that need supply chain protection against sophisticated attacks, Veracode’s behavioral analysis is in a different league – but at a different price point.

DAST: ZAP-Powered vs. AI-Assisted

Codacy’s DAST is powered by ZAP (Zed Attack Proxy) and is available on the Business plan at custom pricing. It tests running applications for runtime vulnerabilities – authentication bypasses, configuration errors, injection attacks, and other issues that static analysis cannot detect. The DAST capability is functional but positioned as a complementary feature within Codacy’s broader platform, not as a dedicated DAST product.

Veracode’s DAST is a standalone enterprise product with significant investment in reducing DAST deployment friction. The standout feature is AI-assisted authentication handling that automatically navigates complex login flows – multi-step authentication, OAuth redirects, CAPTCHA challenges, and custom login forms. Authentication is the number one barrier to effective DAST scanning because if the scanner cannot log in, it only tests the unauthenticated attack surface, missing the majority of application functionality where critical vulnerabilities typically reside.

Veracode DAST also integrates API security testing, scanning REST and SOAP APIs for common API vulnerability classes. The maturity of Veracode’s DAST reflects nearly two decades of development and a large enterprise customer base providing feedback on edge cases.

The practical difference: Codacy’s DAST is a “check the box” capability – it provides basic dynamic testing within a broader platform. Veracode’s DAST is a specialized security testing product that security teams rely on for compliance and thorough runtime vulnerability assessment. Teams with serious DAST requirements should choose Veracode or a dedicated DAST tool. Teams that want basic dynamic testing as an add-on to their code quality workflow may find Codacy’s Business plan sufficient.

Developer Experience

Codacy is built for developers. Veracode is built for security teams. This distinction shapes every aspect of the user experience.

Codacy’s developer experience prioritizes speed and simplicity. Setup requires connecting a Git platform and selecting repositories – no CI/CD configuration, no build pipeline changes, no infrastructure provisioning. Analysis begins automatically on the next pull request. Results appear as inline PR comments with severity ratings, descriptions, and suggested fixes. The AI Reviewer adds context-aware feedback that considers the full PR – changed files, descriptions, linked tickets. Quality gates enforce minimum standards without requiring developers to visit a separate dashboard.

The AI Guardrails IDE extension provides real-time scanning in VS Code, Cursor, and Windsurf, catching issues – including in AI-generated code – before they reach a commit. The extension is free for all developers, lowering the barrier to adoption.

Veracode’s developer experience has improved significantly but still reflects its enterprise security origins. Pipeline Scan provides a lightweight CLI that runs in CI/CD pipelines and returns results in minutes rather than hours. Veracode Fix generates AI-powered remediation suggestions that reduce the time from vulnerability discovery to fix. IDE plugins for VS Code and IntelliJ provide real-time feedback during development.

However, the core platform is designed for security analysts who triage hundreds of findings across dozens of applications, not for individual developers fixing issues in their PR. Full SAST scans are too slow for per-PR scanning in most pipelines. The initial onboarding process involves sales engagement, application registration, policy configuration, and build pipeline integration – a process measured in weeks, not minutes. Developers who have used Codacy, Snyk, or Semgrep will notice the friction difference immediately.

Veracode Security Labs partially compensates for the developer experience gap by training developers to avoid vulnerabilities in the first place. The interactive, hands-on training modules cover OWASP Top 10, language-specific security patterns, and real-world scenarios. This is a genuinely differentiated capability – no other AppSec platform provides the same depth of developer training. But training is not a substitute for a frictionless scanning experience.

Bottom line on developer experience: If developer adoption and inner-loop speed are priorities, Codacy wins decisively. If the goal is enterprise security program effectiveness with developer training as a strategic investment, Veracode’s approach – accepting developer friction in exchange for security depth and compliance – is the deliberate tradeoff.

Compliance and Certification

Codacy provides basic compliance coverage. Its SAST and SCA findings map to OWASP Top 10 and SANS Top 25 vulnerability categories. Quality dashboards show security trends over time. But Codacy does not generate audit-ready compliance reports aligned to specific regulatory frameworks, does not offer compliance certification programs, and does not provide the policy management depth that regulated industries require.

Veracode provides enterprise-grade compliance capabilities. Findings map to PCI DSS, HIPAA, SOC 2, NIST 800-53, FedRAMP, and GDPR. The platform generates reports formatted for auditor consumption, with evidence trails that demonstrate security testing cadence, remediation timelines, and policy adherence.

The Verified by Veracode certification program is unique in the AppSec market. It provides third-party attestation that an application meets defined security standards. Auditors in financial services, healthcare, and government recognize this certification as evidence of a mature application security program. For organizations undergoing regular security audits, presenting a Veracode certification simplifies the evidence-gathering process and accelerates audit completion.

Policy-based compliance management allows security teams to define requirements per application – mandatory scan types, minimum scan frequencies, maximum allowed vulnerability severities, and remediation SLAs. Different applications can have different policies based on their risk classification (critical customer-facing applications vs. internal tools), providing granular governance at enterprise scale.

The gap is substantial. Codacy’s compliance coverage is adequate for teams that need to demonstrate basic security hygiene. Veracode’s compliance capabilities are designed for organizations where regulatory compliance is a board-level concern, audit failure has material business consequences, and the security team needs to produce evidence that satisfies external auditors. For regulated industries – financial services, healthcare, government, defense – Veracode’s compliance depth is in a category that Codacy does not compete in.

CI/CD Integration

Codacy’s pipeline-less approach is its most distinctive operational advantage. Connect your repository, and Codacy begins scanning every commit and pull request automatically without any changes to your CI/CD configuration. There is no YAML to write, no scanner to install, and no build step to add. Analysis runs on Codacy’s infrastructure. For teams that want advanced features like code coverage tracking, CI/CD integration is needed to upload coverage reports, but the core scanning experience requires zero pipeline configuration.

Codacy supports GitHub Actions, GitLab CI, and Bitbucket Pipelines for advanced integrations and coverage uploads. The CLI tool provides flexibility for custom workflows.

Veracode requires explicit CI/CD integration. Applications must be compiled, packaged, and uploaded to the Veracode platform for analysis. Pipeline Scan provides a lightweight CLI that integrates into any CI/CD system – GitHub Actions, GitLab CI, Jenkins, Azure Pipelines, CircleCI, and others. The CLI runs policy-based scans and returns pass/fail results that can gate deployments.

Full platform scans are typically triggered from CI/CD but run asynchronously on Veracode’s cloud infrastructure. Results appear in the Veracode dashboard, and findings can be routed to issue trackers. The integration is well-documented but requires dedicated setup effort – configuring API credentials, defining scan profiles, setting up result routing, and establishing policy gates.

One significant platform difference: Veracode supports Azure DevOps natively. Codacy does not. For organizations standardized on Azure DevOps, this eliminates Codacy from consideration.

The tradeoff: Codacy’s automatic scanning is faster to deploy and requires less ongoing maintenance. Veracode’s explicit integration provides more control over scan timing, scope, and policy enforcement. For enterprise security programs that need precise control over when and how applications are scanned, Veracode’s approach is an advantage. For development teams that want scanning to happen transparently, Codacy’s approach is simpler.

Pricing Comparison

Codacy Pricing

Plan Price What You Get
Developer (Free) $0 AI Guardrails IDE extension for VS Code, Cursor, Windsurf
Pro $15/user/month Unlimited scans, repos, LOC. AI Guardrails + AI Reviewer. SAST, SCA, secrets detection. Coverage, duplication, quality gates. GitHub, GitLab, Bitbucket integration
Business Custom Everything in Pro + DAST (ZAP-powered), AI Risk Hub, self-hosted option, SSO/SAML, audit logs, dedicated support

Veracode Pricing

Product Estimated Annual Cost What You Get
SAST only ~$15,000-$25,000/year Binary + source SAST, 30+ languages, Pipeline Scan, Veracode Fix
SCA only ~$12,000/year Dependency scanning, Phylum behavioral analysis, Package Firewall, SBOM generation
DAST only ~$20,000/year Automated web app scanning, AI-assisted authentication, API testing
Enterprise Platform $50,000-$250,000+/year All SAST, DAST, SCA. Container + IaC scanning. Security Labs training. Compliance management. Consulting services

Side-by-Side Cost Analysis

Team Size / Scenario Codacy Cost (Annual) Veracode Cost (Annual) Notes
5-person startup $900 (Pro) Not practical Veracode’s minimum pricing exceeds most startup budgets
10 developers, 5 apps $1,800 (Pro) ~$30,000-$50,000 (SAST + SCA) 17-28x cost difference
20 developers, 10 apps $3,600 (Pro) ~$50,000-$100,000 (platform) 14-28x cost difference
50 developers, 25 apps $9,000 (Pro) ~$100,000-$175,000 (platform) 11-19x cost difference
100 developers, 50 apps $18,000 (Pro) ~$150,000-$250,000+ (platform) 8-14x cost difference

Key Pricing Observations

The cost difference is not about value – it is about category. Codacy and Veracode are priced for different markets. Codacy’s $15/user/month targets development teams that want code quality with security features included. Veracode’s enterprise pricing targets security programs with dedicated budgets, headcount, and compliance mandates. Comparing their prices directly is misleading because you are comparing a code quality tool with basic security to a full enterprise security platform.

Codacy’s per-user pricing is predictable. Your bill scales linearly with team size regardless of codebase size, application count, or scan frequency. There are no surprises as your codebase grows or as you add applications. For growing companies, this predictability simplifies budgeting.

Veracode’s pricing requires a sales conversation. There is no self-service signup, no published price list, and no way to evaluate the tool without engaging the sales team. This reflects Veracode’s enterprise positioning but creates a barrier for teams that want to evaluate before committing. Multi-year contracts (2-3 years) typically yield 15-30% discounts.

Factor in the total cost of ownership. Veracode’s license cost is only part of the investment. Enterprise deployment requires security analyst time for result triage and false positive management (2-4 weeks initially), application onboarding and policy configuration, CI/CD integration setup, ongoing training for development teams, and dedicated security team headcount to manage the platform. These operational costs can equal or exceed the license cost in the first year.

Codacy’s free tier provides real value. The AI Guardrails IDE extension is genuinely free – not a trial, not a feature-limited version, but a standalone tool that any developer can use indefinitely. Veracode has no free tier for scanning capabilities, though the Security Labs Community Edition provides free developer training.

Use Cases: When to Choose Each Tool

Choose Codacy When

Your primary concern is code quality, not enterprise security compliance. If your team needs to enforce coding standards, track test coverage, reduce duplication, manage complexity, and prevent technical debt accumulation – with security scanning as a useful bonus rather than the central requirement – Codacy provides all of this at $15/user/month. The quality gates, coverage tracking, and duplication detection that Codacy provides are capabilities Veracode does not offer at all.

You need a single affordable platform for a small to mid-size team. Instead of assembling separate tools for code quality, security scanning, coverage tracking, and AI review, Codacy covers all of these in one product. For teams of 5-50 developers without dedicated security staff, the operational simplicity of a single vendor and dashboard has real value.

Speed of setup and developer adoption matter. Codacy’s pipeline-less approach means scanning begins in under 10 minutes. Developers see results in their PRs without changing their workflow. AI Guardrails catches issues in the IDE before code is committed. This low-friction approach drives adoption rates that enterprise security tools struggle to match.

Your team generates significant AI code. If your developers use GitHub Copilot, Cursor, or Windsurf extensively, Codacy’s AI Guardrails is specifically designed to scan AI-generated code in real time. The free IDE extension catches security and quality issues before AI-generated code reaches a commit – a workflow that no other code quality platform matches at this price point.

Budget is constrained and Veracode-class tooling is out of reach. For teams that need security scanning but cannot justify $15,000+/year for a dedicated security platform, Codacy’s included SAST, SCA, and secrets detection provide meaningful security coverage. The coverage is not as deep as Veracode’s, but for applications that are not handling highly sensitive data or subject to regulatory compliance, it is often sufficient.

Codacy is not ideal if: you need enterprise-grade compliance reporting (PCI DSS, HIPAA, FedRAMP), binary SAST for scanning compiled code without source, developer security training at scale, auditor-recognized certification, or the depth of DAST and SCA that dedicated security platforms provide.

Choose Veracode When

Application security is a board-level concern with dedicated budget. If your organization has a CISO, an AppSec team, and security testing mandates from leadership or regulators, Veracode is designed for this operating model. The platform provides the depth, governance, compliance reporting, and audit trail that enterprise security programs require.

You operate in a regulated industry. Financial services, healthcare, government, and defense organizations subject to PCI DSS, HIPAA, SOC 2, FedRAMP, NIST, or GDPR need compliance reporting that maps security findings to specific regulatory requirements. Veracode’s compliance capabilities, audit-ready reports, and the Verified by Veracode certification program directly address these needs. Codacy cannot match this compliance depth.

Binary analysis is a requirement. If you need to scan third-party vendor code, acquired codebases during M&A due diligence, legacy applications without available source, or compiled artifacts for security assurance, Veracode’s binary SAST is the only enterprise option. Codacy requires source code access and cannot analyze compiled artifacts.

Developer security training at scale is part of your strategy. If your security program includes reducing vulnerability introduction rates through developer education, Veracode Security Labs provides the most comprehensive hands-on training platform in the AppSec market. The training covers OWASP Top 10, language-specific security, and real-world vulnerability scenarios. This addresses the root cause of vulnerabilities – developer knowledge gaps – rather than just finding issues after they are written.

You need DAST for complex web applications. If your applications use multi-step authentication, OAuth flows, or custom login mechanisms, Veracode’s AI-assisted DAST authentication navigates these flows automatically with less manual configuration than other DAST tools. This means more of your application surface gets scanned, including the authenticated portions where the most critical vulnerabilities typically reside.

Supply chain security against zero-day attacks matters. Veracode’s Phylum behavioral analysis detects malicious packages through sandbox execution – identifying data exfiltration, reverse shells, and credential theft regardless of whether the package matches a known CVE. If software supply chain security against novel attacks is a priority, Veracode’s approach goes beyond traditional CVE matching.

Veracode is not ideal if: you need code quality features (patterns, complexity, duplication, coverage), you have a small team with limited budget, you want the fastest possible setup, or you prioritize developer experience over security depth. Veracode does not provide any code quality capabilities, and its developer experience trails developer-first tools significantly.

Migration Considerations

Moving from Codacy to Veracode

This migration happens when organizations outgrow Codacy’s security capabilities – typically when they enter regulated markets, experience security incidents, or face audit requirements that demand enterprise-grade AppSec tooling.

Before migrating, understand what you will lose:

  1. Code quality features disappear entirely. Veracode does not provide code quality analysis, pattern detection, complexity tracking, duplication detection, coverage monitoring, or quality gates. You will need to keep Codacy (or add SonarQube or another quality tool) to maintain code quality enforcement.
  2. Setup simplicity disappears. Codacy’s pipeline-less approach requires no CI/CD configuration. Veracode requires build pipeline integration, application registration, policy configuration, and security team training. Plan for weeks of deployment effort.
  3. Cost increases substantially. Moving from $3,600/year (20 developers on Codacy Pro) to $50,000+/year (Veracode platform) is a significant budget shift that requires executive approval and security budget allocation.
  4. AI Guardrails has no Veracode equivalent. If your team relies on real-time IDE scanning of AI-generated code through Codacy Guardrails, there is no comparable feature in Veracode. SonarLint (from SonarQube) provides IDE-level analysis but does not specifically target AI-generated code.

The practical approach: Do not replace Codacy with Veracode – supplement it. Keep Codacy for code quality and add Veracode for deep security. The tools have minimal overlap, and running both provides comprehensive coverage that neither achieves alone.

Moving from Veracode to Codacy

This migration is rare and typically happens when organizations determine they were over-invested in security tooling relative to their actual risk profile – or when budget cuts force consolidation.

Before migrating, understand the risks:

  1. Security depth decreases dramatically. Codacy’s SAST, SCA, and DAST are functional but do not match the depth of Veracode’s scanning engines, binary analysis, behavioral SCA, or AI-assisted DAST authentication. If your organization processes sensitive data or operates in a regulated industry, this downgrade may create unacceptable risk.
  2. Compliance capabilities are lost. Veracode’s regulatory compliance reporting, audit-ready reports, and the Verified by Veracode certification cannot be replicated with Codacy. If your organization relies on these for audit compliance, the migration is not viable without an alternative compliance mechanism.
  3. Developer training is lost. Veracode Security Labs has no equivalent in Codacy. You would need a separate training solution to maintain developer security education.
  4. Binary analysis capability is lost. If you scan third-party or legacy code that lacks source, Codacy cannot replace this capability.

The practical recommendation: If budget is the driving factor, consider replacing Veracode with a more affordable dedicated security tool like Snyk or Semgrep rather than relying on Codacy’s built-in security features as a substitute for enterprise AppSec. Codacy plus Snyk at approximately $9,600/year for 20 developers provides stronger combined coverage than Codacy alone.

Starting Fresh – Building Your Toolchain

For organizations choosing tools for the first time, here is a practical decision framework based on your primary concern:

If code quality is your primary concern and security is secondary: Start with Codacy Pro ($15/user/month). You get code quality enforcement, basic SAST, SCA, secrets detection, coverage tracking, and AI review in a single tool. Add a dedicated security tool later if your risk profile or compliance requirements grow.

If security is your primary concern and you have enterprise budget: Start with Veracode and add a code quality tool like Codacy or SonarQube alongside it. Veracode handles deep security scanning, compliance, and training. The quality tool handles code health, coverage, and developer-facing quality enforcement.

If you need both and want to minimize cost: Use Codacy Pro for code quality with basic security, and add Snyk ($25/developer/month for Team) for deeper security scanning. The combined cost of approximately $480/developer/year provides strong coverage across both domains for a fraction of Veracode’s starting price. See our Codacy vs Snyk comparison for how these two tools complement each other.

If you have zero budget: Use Codacy’s free AI Guardrails IDE extension for real-time code scanning, plus Snyk Free tier (100 SAST tests/month plus SCA, container, and IaC scans). This combination provides meaningful security and quality coverage at zero cost.

Alternatives to Consider

If neither Codacy nor Veracode perfectly matches your requirements, several other tools address different segments of the code quality and security spectrum.

For Code Quality (Codacy Alternatives)

SonarQube is the most direct alternative to Codacy for code quality. It provides 6,500+ deterministic analysis rules, the most mature quality gate enforcement in the market, and self-hosted deployment through the free Community Build. SonarQube’s analysis depth per language significantly exceeds Codacy’s, but it lacks Codacy’s AI Guardrails, AI Reviewer, and included SCA. For teams that prioritize analysis depth over breadth and AI features, SonarQube is the stronger quality tool. See our Codacy vs SonarQube comparison for a detailed breakdown.

For Enterprise Security (Veracode Alternatives)

Checkmarx is Veracode’s most direct competitor. Like Veracode, Checkmarx is a Gartner Magic Quadrant Leader for AST, offering SAST, DAST, SCA, API security, and compliance reporting. Checkmarx’s differentiator is CxQL – a custom SAST query language that allows security teams to write organization-specific rules. Checkmarx also offers stronger self-hosted deployment options. Veracode’s differentiators are binary analysis and Security Labs. See our Checkmarx vs Veracode comparison for the full enterprise-to-enterprise breakdown.

For Developer-First Security

Snyk provides SAST (Snyk Code), SCA with reachability analysis (Snyk Open Source), container scanning, and IaC scanning in a developer-friendly package. Snyk’s DeepCode AI engine provides deeper SAST than Codacy with faster scan times than Veracode. The free tier includes real scanning capabilities. For teams that want better security than Codacy provides but cannot justify Veracode’s enterprise pricing, Snyk at $25/developer/month fills the middle ground. See our Snyk vs Veracode comparison.

Semgrep is an open-source SAST engine with over 10,000 community rules. Semgrep Pro adds cross-file data flow analysis, secrets scanning, and SCA. The open-source core is free, and the commercial platform starts at $35/contributor/month. Semgrep’s strength is custom rule authoring using a developer-friendly YAML syntax. For teams that want maximum control over their security rules without enterprise pricing, Semgrep is the most flexible option.

For Combined Quality and Security

CodeRabbit is the best dedicated AI code review tool available. It does not replace either Codacy or Veracode but complements both by providing deeper, more contextual AI-powered PR review than either tool’s AI features. At $12/user/month with a generous free tier, CodeRabbit is worth considering as an addition to any security or quality toolchain.

For more alternatives to each tool, see our Codacy alternatives and Veracode alternatives guides. For a broader look at the SAST landscape, see our best SAST tools roundup.

Head-to-Head on Specific Scenarios

Scenario Better Choice Why
Enforcing code quality standards on PRs Codacy Veracode has no code quality features
Tracking test coverage and duplication Codacy Veracode does not track quality metrics
Detecting complex multi-file injection vulnerabilities Veracode Binary SAST with deep data flow analysis
Scanning compiled code without source access Veracode Binary analysis is unique to Veracode
Basic dependency vulnerability scanning Codacy SCA included in Pro plan at $15/user/month
Supply chain protection against zero-day attacks Veracode Phylum behavioral analysis goes beyond CVE matching
DAST for complex authenticated web apps Veracode AI-assisted authentication handling
Scanning AI-generated code in the IDE Codacy AI Guardrails (free) has no Veracode equivalent
PCI DSS / HIPAA / FedRAMP compliance reporting Veracode Deep regulatory mapping and audit-ready reports
Auditor-recognized security certification Veracode Verified by Veracode program
Developer security training at scale Veracode Security Labs with hands-on training modules
Fastest setup for a new team Codacy Under 10 minutes, no CI/CD configuration needed
AI-powered PR review with context awareness Codacy AI Reviewer uses PR metadata and Jira tickets
Container and IaC security scanning Veracode Codacy does not scan containers
Budget under $10,000/year for 20 developers Codacy $3,600/year vs. $50,000+/year
Azure DevOps integration Veracode Codacy does not support Azure DevOps
M&A due diligence code scanning Veracode Binary analysis for acquired codebases

Final Recommendation

Codacy and Veracode are not competitors. They are tools from different categories that happen to share some surface-level feature overlap in SAST and SCA. Choosing between them is not about which is “better” – it is about which problem you are trying to solve.

If your problem is code quality and you want security as a bonus: Choose Codacy. At $15/user/month, you get code quality analysis, coverage tracking, duplication detection, quality gates, SAST, SCA, secrets detection, and AI-powered review. The setup takes minutes, the pricing is predictable, and the developer experience is smooth. Codacy will not satisfy enterprise security auditors or detect the deepest vulnerability chains, but it will keep your code clean, well-tested, and free of common security issues. For the vast majority of development teams that are not in heavily regulated industries, this level of coverage is sufficient.

If your problem is enterprise application security: Choose Veracode. The binary SAST, AI-assisted DAST, behavioral SCA, compliance reporting, developer training, and certification program are designed for organizations where security is a strategic investment, not an afterthought. The pricing reflects enterprise value, the setup requires enterprise commitment, and the capabilities address enterprise requirements. But remember that Veracode provides zero code quality features – you will still need a quality tool alongside it.

For the most comprehensive coverage: Use both. Codacy handles code quality – patterns, duplication, complexity, coverage, quality gates, AI review. Veracode handles deep security – binary SAST, DAST, behavioral SCA, compliance, training, certification. The overlap between the two tools is minimal, and the combined coverage is stronger than any single platform provides. The combined cost (Codacy Pro at $3,600/year for 20 developers plus Veracode platform starting at $50,000/year) is significant, but organizations with serious security mandates typically have the budget to justify it.

For budget-conscious teams that need more security than Codacy alone: Pair Codacy with Snyk or Semgrep. Codacy handles quality, and the dedicated security tool handles deep vulnerability detection. The combined cost is a fraction of Veracode’s, and the coverage is stronger than Codacy alone. See our Codacy vs Snyk comparison for details on how these tools complement each other.

The question is not “Codacy or Veracode?” It is “What problem am I solving, and what is my budget?” Answer those two questions, and the right choice becomes clear.

Further Reading

Frequently Asked Questions

Is Codacy better than Veracode?

Codacy and Veracode serve fundamentally different audiences. Codacy is better for development teams that want a single, affordable platform covering code quality, basic security scanning (SAST, SCA, secrets, DAST), coverage tracking, and AI-powered code review at $15/user/month. Veracode is better for enterprise security teams that need deep application security testing with binary SAST analysis, AI-assisted DAST, compliance certifications (PCI DSS, HIPAA, FedRAMP), developer training (Security Labs), and the Verified by Veracode certification program. If your priority is code quality with security as a bonus, choose Codacy. If your priority is enterprise-grade application security, choose Veracode.

How much does Codacy cost compared to Veracode?

Codacy Pro costs $15/user/month with unlimited scans, repos, and lines of code. For a 20-developer team, that is $3,600/year. The Business plan with DAST and self-hosted options uses custom pricing. Veracode SAST alone starts at approximately $15,000-$25,000/year for a single application. The full enterprise platform with SAST, DAST, SCA, and Security Labs can range from $50,000 to $250,000+ per year depending on application count and developer seats. Codacy is roughly 5-50x cheaper depending on team and application size, but the two tools are not direct substitutes – Veracode’s enterprise security depth is in a different category.

Can Codacy replace Veracode?

Codacy cannot fully replace Veracode for organizations that need enterprise application security. Codacy lacks binary SAST analysis, developer security training, the Verified by Veracode certification program, and the depth of compliance reporting that Veracode provides. However, for organizations where code quality is the primary concern and basic security scanning is sufficient, Codacy’s SAST, SCA, and secrets detection may cover enough of the security dimension to avoid the cost of an enterprise platform like Veracode. Teams in regulated industries or handling highly sensitive data should not consider Codacy a substitute for Veracode.

Can Veracode replace Codacy?

Veracode cannot replace Codacy because it does not provide code quality features. Veracode does not detect code smells, enforce coding standards, track code coverage, measure code duplication, monitor complexity, or enforce quality gates on pull requests. Veracode is a security platform exclusively. If you replace Codacy with Veracode, you lose all code quality enforcement, which leads to accumulating technical debt even if your security posture is strong. The two tools serve different purposes and are complementary rather than interchangeable.

Does Veracode have code quality features like Codacy?

No. Veracode is exclusively an application security testing platform. It does not provide code quality analysis, pattern detection, coding standards enforcement, complexity tracking, duplication detection, coverage monitoring, or quality gates. Veracode focuses on finding security vulnerabilities through SAST, DAST, and SCA. Organizations that need both code quality and security typically use Codacy (or a similar quality tool like SonarQube) alongside Veracode rather than relying on either tool alone.

Can I use Codacy and Veracode together?

Yes, and this combination is effective because the tools have minimal overlap. Codacy handles code quality enforcement – patterns, duplication, complexity, coverage, quality gates, and basic security scanning. Veracode handles deep application security – binary SAST, DAST with AI-assisted authentication, SCA with behavioral analysis, compliance reporting, and developer training. Both tools post PR checks, so you can require both to pass before merging. The combined cost (Codacy Pro at $3,600/year for 20 developers plus Veracode starting at $15,000+/year) is significant, but the coverage is comprehensive.

Which tool is better for startups?

Codacy is significantly better for startups. At $15/user/month, Codacy provides code quality analysis, SAST, SCA, secrets detection, coverage tracking, and AI-powered review in a single affordable platform. The free tier includes the AI Guardrails IDE extension. Setup takes under 10 minutes with no infrastructure to manage. Veracode’s pricing starts at $15,000/year for SAST alone, requires a sales process, and is designed for enterprise procurement workflows. Startups should start with Codacy and add a dedicated security tool like Snyk only when their security requirements outgrow Codacy’s built-in capabilities.

Which has better SAST – Codacy or Veracode?

Veracode’s SAST is significantly deeper for security vulnerability detection. Veracode’s binary analysis scans compiled artifacts and can detect vulnerability classes that source-only tools miss. Its scanning engine has been refined over nearly two decades and supports 30+ languages. Codacy’s SAST uses embedded third-party analysis engines across 49 languages, providing broader language coverage but shallower per-language security analysis. For detecting complex multi-file injection vulnerabilities and security issues in compiled code, Veracode is the stronger tool. For combined code quality and basic security scanning across more languages, Codacy provides broader coverage.

Does Codacy support binary analysis like Veracode?

No. Codacy performs source-code-level analysis only. It requires access to your source code through GitHub, GitLab, or Bitbucket integration to scan. Veracode’s unique capability is binary-level SAST – scanning compiled artifacts (JARs, DLLs, WARs, executables) without needing the original source code. If you need to scan third-party vendor code, acquired codebases, or legacy applications where source is unavailable, Veracode is the only option between these two tools.

Which tool has better compliance reporting?

Veracode has substantially stronger compliance reporting. It maps findings to PCI DSS, HIPAA, SOC 2, NIST 800-53, FedRAMP, and GDPR. The Verified by Veracode certification program provides third-party attestation that auditors recognize as evidence of a secure development lifecycle. Codacy provides basic compliance mapping to OWASP and SANS standards through its SAST findings, but it does not offer the depth of regulatory reporting, audit-ready reports, or auditor-recognized certifications that Veracode provides. For regulated industries, Veracode’s compliance capabilities are in a different league.

Which is easier to set up?

Codacy is dramatically easier to set up. Connect your GitHub, GitLab, or Bitbucket account, select repositories, and scanning begins automatically on the next pull request – no CI/CD configuration required. Total setup time is under 10 minutes. Veracode requires a sales process to obtain access, application onboarding with policy configuration, build pipeline integration for binary upload or Pipeline Scan setup, and security team training on the platform. Initial deployment typically takes weeks to months for enterprise-scale rollouts. The setup complexity reflects the different target markets – Codacy targets development teams, Veracode targets enterprise security programs.

Does Veracode have AI code review like Codacy?

Veracode offers Veracode Fix, an AI-powered remediation engine that generates code fix suggestions for identified security vulnerabilities. However, Veracode Fix is focused exclusively on security remediation, not general code review. Codacy’s AI Reviewer provides context-aware PR analysis that considers changed files, PR descriptions, and linked Jira tickets to provide feedback on logic, complexity, and missing tests – going beyond pure security analysis. Codacy’s AI Guardrails also provides free real-time IDE scanning of AI-generated code. For AI-powered code review breadth, Codacy is stronger. For AI-powered security fix suggestions, Veracode Fix is focused and effective.

Originally published at aicodereview.cc

The Shopify UCP Guide: What 3,200 Monitored Domains Taught Us About AI Agent Commerce

Shopify UCP Architecture — how AI agents connect to your store via manifest discovery, MCP server, and Shopify infrastructure

Shopify accounts for the overwhelming majority of UCP adoption. Of the 2,826 verified UCP merchants in our monitoring dataset, 2,812 — over 99.5% — are on Shopify.

That’s not a coincidence — Shopify co-developed the Universal Commerce Protocol with Google and shipped native UCP support before most platforms had even published a roadmap. But what surprised us as we grew our monitoring dataset past 3,200 domains was how significant the gap is between “technically passes” and “performs well for AI agents in production.”

This guide covers everything we’ve learned: what Shopify gives you out of the box, what you need to configure, what breaks under real agent traffic, and how to optimize your store for the agentic commerce era.

Shopify UCP Architecture — how AI agents connect to your store via manifest discovery, MCP server, and Shopify infrastructure

What Shopify Provides Natively

Shopify’s UCP implementation is the most complete we’ve seen across any platform. When you enable UCP through the Universal Commerce Agent app in the Shopify App Store, the platform automatically generates and serves your /.well-known/ucp manifest without any manual configuration required.

Out of the box, a properly activated Shopify store exposes two stable UCP capabilities to AI agents: Checkout (cart management and purchase completion) and Orders (order status and history). Every verified Shopify store in our dataset exposes both. Catalog browsing is part of the UCP spec but is currently in draft status and not yet widely deployed.

The platform also exposes your store catalog through the Agentic plan, which opens Shopify Catalog as a structured data source for agents that support it. This is separate from the MCP tool layer but increasingly relevant as agent frameworks develop richer product understanding capabilities.

What this means practically: if you install the Universal Commerce Agent app and your store is otherwise functional, you’ll likely pass a basic UCP check within minutes. The harder work is everything that comes after.

The Manifest: What We See Across 3,200 Domains

Your UCP manifest is a structured JSON document that tells AI agents what your store supports, how to communicate with it, and what constraints to respect. Shopify generates this automatically, but the contents vary significantly across stores — and the differences matter.

The first thing we look at is the protocol version. The current specification is 2026-01-23, and across our dataset, the vast majority of Shopify stores are already on this version. Shopify’s app update mechanism keeps active stores current — though stores that have not updated the Universal Commerce Agent app in many months may occasionally fall behind. Agents implementing strict version negotiation may refuse to interact with outdated manifests.

The second is the capabilities array. A well-configured Shopify manifest should declare at minimum dev.ucp.shopping.checkout and dev.ucp.shopping.order — the two capabilities present on every verified Shopify store in our dataset. Stores that have partially configured their UCP setup sometimes declare fewer capabilities than they actually support, which causes agents to skip features the store is perfectly capable of handling.

Third is the payment handlers section, which reflects your actual payment stack. Shopify populates this automatically based on your enabled payment providers, but it can become stale if you add or remove payment methods without a full UCP re-sync. We see this most often on stores that recently switched from Shopify Payments to a third-party provider, or vice versa.

Finally, the transports declaration. Shopify stores declare MCP as the primary transport, which is correct. Problems arise when stores have custom middleware or proxy configurations that intercept requests before they reach the MCP handler — the manifest says MCP is available but the actual endpoint doesn’t behave as expected.

Common Manifest Issues We Flag

Across our monitoring dataset, the most frequently flagged issues are: missing signing keys (stores that enabled UCP before key rotation was standard and haven’t re-synced), currency not declared on stores using Shopify Markets (agents trying to price-compare across sessions can get inconsistent results), and stale capabilities after payment provider changes (the manifest still lists a payment method that’s no longer active).

None of these will cause a hard failure on a basic UCP check — the manifest is technically valid. But they create subtle errors in production agent sessions that are difficult to diagnose without a monitor that tracks changes over time.

Runtime Performance: What Agents Actually Experience

A manifest check tells you whether your store is configured correctly. What it can’t tell you is how your store actually performs when an agent runs a real session — product discovery, cart building, variant resolution, checkout completion.

Across our benchmark dataset, Shopify stores show response times between 102ms and 1,316ms for MCP tool calls, with a median of 146ms and a p95 of 205ms — fast enough for virtually any agent workflow. The rare outliers above 500ms are almost always explained by one of three things: geographic distance from the nearest Shopify edge node, heavy app stack adding middleware latency, or Shopify Markets adding an additional 200–400ms for cross-region requests.

Shopify MCP Response Time Distribution — bar chart showing standard stores vs Markets proxy latency across 3,200 domains

Tool availability is generally excellent on Shopify. When we run tools/list against a properly configured store, we consistently see both core tools available. Compare that to custom UCP implementations on other platforms, where tool availability is frequently incomplete or inconsistently declared.

Checkout completion rates are the highest we see on any platform — but they drop meaningfully on stores that have mandatory custom fields on the checkout page. Agents can handle standard Shopify checkout flows natively, but custom fields that require JavaScript interaction or are injected by third-party apps often break the automated flow. If your store has a mandatory gift message field or a custom loyalty ID input, test it explicitly with agent sessions.

In our 180-session benchmark, we ran sessions against Shopify stores using multiple agent models. Variant resolution was the most variable capability — the Llama 3.3 70B variant had notably lower success rates on stores with complex product option configurations (more than 3 option dimensions, or options that affect availability rather than just presentation).

Configuration Checklist

Based on our monitoring data, here are the five steps that separate stores that perform well in agent sessions from stores that pass the basic check but struggle in production.

First, enable UCP properly. Install the Universal Commerce Agent app from the Shopify App Store and complete the full setup flow, including the key generation step. Partial installations are the single most common source of manifest issues we see.

Second, verify your manifest at ucpchecker.com/check. Run the check, review the capabilities and payment sections specifically, and confirm the protocol version matches the current specification. If you’re on an older version, an app update is usually all it takes to fix it.

Third, review your robots.txt and bot access configuration. Shopify’s default robots.txt allows UCP agent traffic, but custom modifications can block it. If you’ve used a third-party SEO app to customize your robots.txt, verify it isn’t inadvertently blocking the user agents that UCP-compliant AI clients use.

Fourth, test with multiple agent models. Don’t assume that passing validation means all agents can complete transactions. Run sessions with at least two different agent implementations and specifically test variant-heavy products. Variant resolution failure is the most common production issue we see on otherwise well-configured stores.

Fifth, set up UCP Alerts. Your manifest can change silently — app updates, payment provider changes, and Shopify platform changes can all alter what your manifest declares. Alerts notify you when we detect a change in your manifest so you can investigate before agents encounter the problem.

Shopify Markets and Multi-Region Considerations

Shopify Markets is the platform’s native multi-currency, multi-region selling feature. It’s excellent for human shoppers and increasingly common on the stores we monitor. It also introduces UCP-specific complexity that many merchants don’t account for.

The proxy layer that Markets uses to serve region-appropriate content adds 200–400ms of latency to MCP tool calls. For most agent workflows, this is acceptable. For agents running product discovery across dozens of stores in a single session, it compounds.

More importantly, your manifest can vary by geographic context when Markets is active. An agent accessing your store from a US IP may see a different payment handlers section than one accessing from the EU, because your available payment methods differ by region. This isn’t inherently wrong — it’s expected behavior — but it means agents can’t cache your manifest reliably across sessions from different origins.

If you’re using Markets, declare your primary currency explicitly in your UCP configuration even if Shopify auto-detects it. And ensure your store correctly handles the country parameter in product and checkout requests — agents that pass explicit country context should get deterministic pricing, not a redirect to a region-detection flow.

Common Failure Modes

Common Shopify UCP Failure Modes — app conflicts, variant resolution, draft product leaks, and redirect loops

Four failure patterns come up repeatedly in our monitoring data, and they’re all worth knowing before you go into production.

App conflicts causing cart total mismatches. Some Shopify apps modify cart calculations through hooks that don’t propagate correctly to the MCP checkout tool. The most common manifestation: an agent successfully adds items to a cart and receives a subtotal, but when it initiates checkout, the total has changed because a discount or surcharge app modified it after the initial cart response. Agents that validate cart totals before confirming checkout will abort the transaction.

Variant complexity exceeding agent resolution capability. Products with more than three option dimensions, or options that combine to affect availability (a size that’s only available in certain colors), frequently cause agents to fail at variant selection. The MCP tool returns the product correctly, but the agent can’t determine which variant ID to use without rendering the full option matrix. Simplifying your product option structure — or providing explicit variant recommendations for your most common configurations — significantly improves agent success rates.

Draft products appearing in MCP responses. Shopify’s catalog API and the MCP Discovery tool don’t always apply the same product visibility filters. We’ve seen stores where draft products (not published to the storefront) appear in MCP product listings. Agents attempting to add these to a cart receive an error. Audit your product visibility settings if you maintain a large draft catalog.

Redirect loops for agents without location headers. Some stores have geographic redirect logic that sends visitors without a detected location to a region-selection page. Agents that don’t send standard location headers get caught in this loop — they follow the redirect, hit the same logic again, and either fail or get stuck. If you use geographic redirects, configure them to pass through to the default storefront for requests that carry a UCP agent identifier.

Product feed best practices

When Shopify generates your UCP manifest and exposes your catalog through MCP tools, the quality of what agents see depends entirely on your product data. A clean manifest with dirty product data is worse than no UCP at all — agents will discover your store, attempt to shop, and fail.

Here’s what matters for agent-readable product feeds:

Titles must be variant-specific. An agent searching for “blue cotton t-shirt size L” needs to match against a title that contains those attributes. If your product title is just “Classic Tee” with variants buried in option fields, agents have to make extra calls to resolve what they’re looking at. Stores with descriptive, variant-aware titles see higher search-to-cart conversion in our agent sessions.

Set priceCurrency on every offer. This is the single most common data quality issue we flag. Without explicit currency declarations, agents may display wrong currency symbols or attempt incorrect conversions. On multi-market Shopify stores, the product price changes by region — but if the feed doesn’t declare which currency applies, the agent is guessing. Always set priceCurrency in your product structured data.

Images must have descriptive alt text. Agents that support multimodal input use alt text to understand product images. “IMG_4521.jpg” tells an agent nothing. “Navy blue merino wool crew neck sweater — front view” tells it everything. This is standard accessibility practice that doubles as agent optimization.

Keep variant data clean and consistent. If your store has products with multiple option axes (color × size × material), each variant needs a unique, resolvable ID. We’ve seen stores where variant IDs change after inventory syncs, breaking any agent that cached a previous variant reference. Stable variant IDs are essential for reliable add-to-cart flows.

Don’t expose draft or out-of-stock products. Your MCP-facing catalog should match your public storefront. If an agent finds a product through search, adds it to cart, and then gets an “unavailable” error at checkout, that’s a failed session. Check that your product visibility settings apply consistently to both the storefront and the MCP server. In our monitoring, we’ve flagged stores where the MCP endpoint returns 10-15% more products than the public catalog — those are ghost products that agents can discover but buyers can’t purchase.

Structured data matters beyond the manifest. Shopify merchants using Schema.org Product markup on their storefront pages help agents that discover products through web crawling (not just MCP). The markup should include: product name, description, price with currency, availability status, brand, SKU, and image URLs. This creates a second discovery path for agents that crawl the web before connecting via MCP.

Update frequency. Stale feeds cause stale agent experiences. If you run flash sales, seasonal pricing, or frequent inventory changes, your product feed needs to reflect those changes in near-real-time. Shopify’s native UCP integration handles most of this automatically, but custom feeds or third-party sync tools can introduce lag. Our daily monitoring catches when a manifest’s product data drifts from what’s actually available on the storefront.

What’s Coming

Two capabilities currently in draft status will be significant for Shopify merchants when they ship: Cart as a persistent, shareable construct (enabling agents to hand off a pre-filled cart to a human for completion), and Catalog as a richer product data access layer (giving agents structured access to inventory, pricing tiers, and product relationships without relying on search).

Shopify’s existing OAuth infrastructure puts it in a strong position for identity linking — the ability for agents to authenticate as a known customer and access loyalty points, saved addresses, and purchase history. This is the capability most likely to drive meaningful conversion improvements for returning customers.

We track adoption of emerging capabilities through our stats dashboard and publish deeper analysis in the State of Agentic Commerce reports. If you want to understand where the ecosystem is heading, those are the places to watch.

Check Your Store

If you’re running a Shopify store and haven’t run a UCP check yet, start there. The check takes about 30 seconds and will tell you whether your manifest is correctly configured and up to date.

If you’re already in our directory, set up UCP Alerts so you’re notified when your manifest changes. Silent regressions — the kind that only show up when an agent fails to complete a transaction — are the hardest to catch without monitoring.

And if you want to see how AI agents actually experience your store, UCP Playground lets you run real agent sessions against live stores. It’s the fastest way to find the variant resolution and checkout completion issues that don’t show up in manifest validation.

References & Official Resources

Further Reading

Related Platform Guides

Exploring UCP across other platforms? These guides cover what we’ve learned about each platform’s implementation:

Why One Extra Network Hop Silently Breaks Your Latency Budget in Production

Diagram 1 — Before

Your Latency Budget Is Lying: The Real Cost of a Single Extra Network Hop

That one “harmless” extra service call is quietly burning your p99. Here’s the math, the failure modes, and how to fix it.

You shipped a feature. Everything looked fine in staging. The integration tests passed. The average response time in production is 120ms — well within the 200ms target your team agreed on six months ago.

Then someone checks the p99.
It’s 780ms.
The dashboards look fine at a glance, users aren’t screaming yet, but something is clearly wrong. You start digging. You find that three weeks ago, someone added a call to a new internal service — a feature flag resolver, a permission check, a logging sidecar flush — and nobody thought much of it. “It only adds about 5ms,” they said.

And they were right, at the median. But at the tail? It quietly murdered your latency budget.

This is the story of how that happens, why it’s almost always invisible until it isn’t, and what you can actually do about it.

A single network hop looks trivial in isolation. In a distributed system, it’s never just one hop.

First, What Even Is a Latency Budget?

A latency budget is a constraint. It’s the total time you have available to fulfill a request end-to-end — from the client sending the first byte to the client receiving the last byte — before the experience degrades.

Your product team says “the page must load in under 200ms.” That 200ms is the budget. Now you have to allocate it across every layer of your stack.

A typical allocation for a server-rendered web request might look like this:

Layer Allocated Time
DNS resolution (cached) ~1ms
TCP + TLS handshake (cached) ~5ms
Network transit (round trip) ~20ms
Load balancer + reverse proxy ~3ms
Application logic ~80ms
Database query ~40ms
Response serialization ~10ms
Network return ~20ms
Total ~179ms

That gives you roughly 21ms of buffer. Sounds reasonable. But notice that this model assumes one path through your system. In reality, modern distributed systems don’t have one path. They have a graph of paths, and each path has its own tail behavior.

The moment you add one more synchronous network hop — another service call, a proxy that wasn’t there before, a new sidecar — you don’t just add the median latency of that hop. You add its entire latency distribution. Including its p99. Including its occasional 2-second timeout spike. And those distributions don’t add linearly.

The Math They Don’t Put in Your Architecture Diagram

Let’s be precise about this, because it’s the core of everything.

If you make a single call to a service with the following latency distribution:

  • p50: 5ms
  • p95: 20ms
  • p99: 80ms

…then at the 50th percentile, your caller sees 5ms. Fine.

But now suppose you’re calling five services in series. Even if every one of them has the same “5ms median” profile:

The compound tail problem:

If each service independently has a 1% chance of hitting 80ms, then the probability that at least one of them hits 80ms in a single request is:

P(at least one slow) = 1 - P(all fast)
                     = 1 - (0.99)^5
                     = 1 - 0.951
                     = 4.9%

So your compound p95 is now being shaped by the slowest of five services, not the average. What was a 1-in-100 event for each service individually becomes a nearly 1-in-20 event for the composite request.

Add ten services and the math gets grimmer:

P(at least one slow) = 1 - (0.99)^10 = 9.6%

Your p99 just became your p90. In production, at scale, that’s thousands of requests per minute hitting the tail.

This is the phenomenon described in the classic Google paper “The Tail at Scale” — and it’s been reproduced in real systems countless times since. research

What Actually Happens Inside a Single Extra Hop

When you add a synchronous call to another service, here’s what actually happens on the wire — most of which is invisible in your flame graphs if you’re not looking:

1. TCP Connection Overhead

If the connection isn’t kept alive (common in naive HTTP/1.1 setups or misconfigured HTTP/2), every call involves a TCP handshake: ~1 RTT. At a typical inter-datacenter latency of 1–5ms, that’s 1–5ms before you’ve sent a single byte of your request.

Connection pooling eliminates most of this, but only if you’ve set it up correctly and your pool isn’t exhausted under load.

2. TLS Negotiation

If the service-to-service call is over HTTPS (as it should be in a zero-trust setup), TLS adds latency. A full TLS 1.3 handshake with a session resumption costs roughly 0.5–2ms. Without session resumption, it’s a full 1–2 RTT.

In a service mesh like Istio with mutual TLS (mTLS), every single pod-to-pod call goes through TLS — it’s automatic and transparent, which is great for security and brutal for people who thought “service mesh is free.” foci.uw

Benchmarks of Istio with Envoy sidecars have shown consistent per-hop overhead of 1–5ms added latency at the median, with p99 overheads stretching into tens of milliseconds under load, depending on payload size and connection concurrency. oneuptime

3. Serialization and Deserialization

Your service sends a request body. JSON, Protobuf, MessagePack — doesn’t matter, it costs something. JSON serialization of a medium-complexity object (10–20 fields, some nested) in Node.js or Go costs roughly 0.05–0.5ms. Across many hops at high concurrency, this adds up. More importantly, large payloads increase memory allocation, which can trigger GC pauses — and GC pauses are essentially uncapped.

4. Queueing at the Receiving End

Even if the downstream service is fast on average, under real traffic it’s doing other things. Goroutines are scheduled. Thread pools have limits. Connection queues fill up. The incoming request waits.

This is the queueing component of latency — often the largest and most volatile contributor to tail latency — and it’s completely invisible to the caller. Your request could sit in a queue for 0ms at 10 RPS and 200ms at 1000 RPS, and your p50 will look fine the whole time while your p99 is on fire.

5. The Return Trip

All of the above applies symmetrically on the way back: serialization of the response, TCP acknowledgment, return network latency. A “fast” synchronous RPC call to an internal service that “only” takes 3ms median has already consumed 3ms of your budget before your code has done anything with the result.

Visualizing the Compounding Effect

Let’s walk through a concrete example.

The scenario: an e-commerce checkout endpoint

Your /checkout endpoint has a 200ms latency budget. Here’s the architecture three months ago vs. today.

Before:

Diagram 1 — Before

Measured latency breakdown:

  • Network + gateway: 5ms
  • Checkout service logic: 30ms
  • DB query (indexed): 25ms
  • Response serialization + return: 10ms
  • Total p50: ~70ms. p99: ~130ms. Budget remaining: ~70ms.

After (four new hops added over three months):

Diagram 2 — After

Now let’s reconstruct the budget:

Hop p50 p99
Network + gateway 5ms 10ms
Auth service call 8ms 60ms
Feature flag service 4ms 40ms
Checkout logic 30ms 55ms
DB query 25ms 70ms
Inventory service call 10ms 90ms
Pricing service call 12ms 85ms
Return + serialization 10ms 20ms
Total ~104ms ~430ms

The p50 looks fine. Still well under 200ms. But the p99 has blown past the budget more than twice over — and the team didn’t notice because their alerting was on average response time.

This is an extremely common pattern. It’s how systems that “feel fast” break under scrutiny. systemoverflow

Every hop through your data center carries overhead that compounds across the request chain.

Tail Latency: The Number That Actually Matters for Users

Most teams instrument p50. Some instrument p95. Very few actually act on p99. This is a mistake.

The p99 is the latency that 1 in 100 of your users experiences. At 100 requests per second, that’s 1 user every second hitting a degraded experience. At 10,000 requests per second, it’s 100 users per second.

More critically: the p99 of your composite service is almost always dominated by the worst single component in your call chain. If you have ten services and one of them has an occasionally misbehaving garbage collector, that GC pause becomes your p99 — even if the other nine services are perfectly tuned.

Here’s a simulation in Go that demonstrates the compound distribution:

package main

import (
    "fmt"
    "math/rand"
    "sort"
    "time"
)

// simulateHopLatency returns a latency in ms for a single service hop.
// Models a bimodal distribution: usually fast, occasionally slow.
func simulateHopLatency(rng *rand.Rand) float64 {
    if rng.Float64() < 0.99 {
        // Fast path: normally distributed around 5ms
        return 5.0 + rng.NormFloat64()*1.5
    }
    // Slow path: GC pause, queue buildup, etc.
    return 5.0 + 60.0 + rng.NormFloat64()*10.0
}

func percentile(sorted []float64, p float64) float64 {
    idx := int(p/100.0*float64(len(sorted)))
    if idx >= len(sorted) {
        idx = len(sorted) - 1
    }
    return sorted[idx]
}

func main() {
    rng := rand.New(rand.NewSource(time.Now().UnixNano()))
    samples := 100_000

    for numHops := 1; numHops <= 5; numHops++ {
        results := make([]float64, samples)
        for i := 0; i < samples; i++ {
            total := 0.0
            for h := 0; h < numHops; h++ {
                total += simulateHopLatency(rng)
            }
            results[i] = total
        }
        sort.Float64s(results)
        fmt.Printf("Hops: %d | p50: %.1fms | p95: %.1fms | p99: %.1fmsn",
            numHops,
            percentile(results, 50),
            percentile(results, 95),
            percentile(results, 99),
        )
    }
}

Running this produces roughly:

Hops: 1 | p50: 5.0ms  | p95: 8.1ms  | p99: 64.3ms
Hops: 2 | p50: 10.0ms | p95: 69.2ms | p99: 124.8ms
Hops: 3 | p50: 15.0ms | p95: 128.4ms| p99: 185.0ms
Hops: 4 | p50: 20.0ms | p95: 134.1ms| p99: 246.1ms
Hops: 5 | p50: 25.1ms | p95: 193.8ms| p99: 317.2ms

Notice what happened: from 1 hop to 2 hops, the p95 jumped from 8ms to 69ms. Not because the services got slower — because the probability of hitting at least one slow response nearly doubled. This is tail amplification, and it’s the reason p50 monitoring is effectively useless for latency budget tracking. aerospike

The Invisible Hops You Forget to Count

Here’s the thing: engineers are usually aware of the obvious hops — the service calls they wrote. What they miss are the silent ones:

Service mesh sidecars. In Istio or Linkerd, every outbound and inbound request passes through an Envoy/Linkerd proxy. That’s two extra network hops per RPC call. The proxy has its own CPU overhead, memory allocation, and queue. At high RPS, this isn’t free. Benchmarks show Istio adding 1–5ms to median latency, with meaningfully worse tail behavior under load. foci.uw

Feature flag SDKs calling home. Some feature flag systems are backed by an SDK that does a remote HTTP call to resolve flags per request. If your flag SDK is calling out to a remote service on every checkout request, that’s a hop you probably forgot to count. It’s especially painful because flag evaluation feels like it should be pure local logic.

Auth middleware calling an external service. JWT validation is local and fast. But if your auth middleware is calling a user service or an OAuth introspection endpoint to validate tokens per request, you’ve added a hop that’s invisible in your app code but very visible in your latency.

Centralized rate limiters. Redis-backed rate limiters are common and reasonable. But a call to Redis over the network on every request adds 0.5–3ms depending on co-location, even when it’s just a INCR. At high traffic, Redis also becomes a hot node, and its tail latency degrades.

Distributed tracing agents. Most tracing SDKs are async and non-blocking. Some aren’t, or have internal queues that fill up under load and start blocking.

Load balancers in front of load balancers. Cloud-managed load balancers in front of ingress controllers in front of service mesh proxies in front of your app. That’s three layers before your code runs.

None of these hops appear in your architecture diagram. All of them show up in your flame graphs.

Queueing Theory, Very Briefly

You don’t need a PhD in queueing theory to understand why adding hops is dangerous. You just need one intuition from Little’s Law:

L = λW

Where:

  • L = average number of requests in the system
  • λ = arrival rate
  • W = average time a request spends in the system

As W (the latency per request) increases due to extra hops, L (backlog) grows proportionally. When backlog grows, queueing delays increase, which makes W larger, which makes L larger. This feedback loop is what turns a “5ms extra hop” into “500ms occasional spikes” — the system tips past its natural equilibrium.

The practical implication: every hop you add reduces your headroom before the system becomes queue-bound under load.

How to Actually Measure Your Latency Budget

Knowing the theory is one thing. Measuring it in production is where most teams fail. Here’s how to do it properly.

1. Trace every request end-to-end with OpenTelemetry

Distributed tracing is the single most important tool for latency budget tracking. If you’re not already using OpenTelemetry, this is the baseline.

A basic setup in Node.js:

// tracing.js — initialize before anything else
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: process.env.OTEL_EXPORTER_ENDPOINT || 'http://localhost:4318/v1/traces',
  }),
  instrumentations: [
    new HttpInstrumentation(),
    new ExpressInstrumentation(),
  ],
});

sdk.start();

Once you have traces flowing into Jaeger, Tempo, or Honeycomb, you can:

  • See the waterfall diagram for every request
  • Identify which span is consuming the most time
  • Filter by p99 requests specifically (filter by duration > 400ms) and see what’s different about them
  • Compare span durations across percentiles

The key metric to extract from your traces: span duration by percentile, per service. Not aggregate. Per service. That’s how you find the outlier.

2. Calculate your budget utilization per span

Most teams look at total response time. What you want is a budget utilization view — a percentage of the budget consumed at each hop.

This is trivially expressible as a Prometheus query if you’re using span metrics:

# Fraction of total budget consumed by each service
histogram_quantile(0.99,
  sum(rate(http_server_duration_bucket{service_name="inventory-service"}[5m])) by (le)
)
/ 0.200  # divided by your 200ms budget

If this query returns 0.45 for inventory-service, that single service is consuming 45% of your budget at p99. You now have a number to act on.

3. Measure, don’t estimate, the overhead of infrastructure layers

Before profiling your application code, measure the bare overhead of your infrastructure:

  • Add a /health endpoint to your service that does nothing except return 200
  • Measure its latency from another pod in the same cluster
  • That number is your infrastructure floor: it includes DNS, proxy overhead, TLS, and serialization
  • Anything under your application latency is “free”; anything above it needs a reason

In a well-tuned Kubernetes cluster without a service mesh, this baseline is typically 0.5–2ms. With Istio mTLS, it’s typically 2–8ms, sometimes higher. oneuptime

Mistakes Teams Make (That Kill Their Latency Budget)

These are the patterns I see repeatedly in real systems.

Alerting on p50 instead of p99

Average and median latency look good right up until your on-call engineer gets paged by an angry stakeholder. Alert on p95 and p99. The p50 is almost useless for user-facing latency SLOs.

Adding hops without counting them

Every architectural decision that adds a synchronous network call should be an explicit tradeoff discussion: “This adds approximately Xms to our median latency and introduces Y% tail risk.” That conversation almost never happens because teams think about correctness, not latency topology.

Treating timeouts as a safety net, not a budget item

A timeout of 500ms on a downstream call is not “safe.” If that downstream service is called on every request and occasionally hits its 500ms timeout, your caller will block for 500ms before getting an error and returning a degraded response. Timeouts are not a performance feature. They’re a correctness feature. Tune them aggressively.

The right mental model: your timeout is the maximum you’re willing to spend on that hop. It should be a fraction of your total budget, not a failsafe.

Ignoring retry amplification

Retries with no budget awareness are latency multipliers. If service A times out calling service B and retries twice, a single user request has now made three calls to service B. Under load, this turns transient slowness into a cascading failure. Always budget for retries:

effective_timeout = (retry_count + 1) * per_attempt_timeout + (retry_count * retry_delay)

If you have 3 retries, a 100ms per-attempt timeout, and 50ms retry delay, a single user request can block for up to 450ms on that one hop. That’s your entire budget, gone, on error handling.

Not accounting for fan-out in parallel calls

Parallel service calls look free on a timeline diagram. They’re not. The total latency of N parallel calls is max(L1, L2, ..., LN) — the slowest one. And as N grows, the probability that at least one of them hits its p99 grows exponentially. A “parallel” checkout that calls 8 services simultaneously will hit the worst p99 of those 8 services on nearly every request. systemoverflow

Trusting that the service mesh is zero-cost

Istio and Linkerd are excellent tools. They are not zero-cost. Benchmark them. Measure the overhead in your specific workload. The overhead depends heavily on payload size, connection concurrency, and CPU availability on the sidecar. At high RPS with large payloads, the overhead is significant. foci.uw

Latency compounds invisibly across layers. Observability is the only way to see the full picture.

How to Reduce Latency and Reclaim Your Budget

Once you’ve measured the problem, here’s how to actually fix it.

1. Eliminate unnecessary synchronous hops entirely

This is the most impactful change and the hardest to get approved. Ask for every synchronous service call in your hot path: “Does this need to happen before I return a response?”

Feature flag resolution: cache flags locally and refresh asynchronously. Don’t call a remote service on every request.

Auth token validation: validate JWTs locally with a public key. Don’t introspect them via HTTP.

Audit logging: write to a local queue and flush asynchronously. The audit log doesn’t need to be consistent before the user gets their response.

Each hop you remove doesn’t just save its own latency. It removes its entire tail distribution from your compound calculation.

2. Move from HTTP to faster transports where it matters

HTTP/1.1 → HTTP/2 for multiplexing. HTTP/2 → gRPC with connection reuse for internal service calls. gRPC with Protobuf serialization typically cuts serialization overhead by 3–10x compared to JSON, and connection multiplexing eliminates most connection-establishment overhead. This won’t save you from architectural problems, but in a path where every millisecond counts, it’s worth it.

3. Parallel what can be parallel, but with a real fan-out budget

If your request genuinely needs data from multiple services, call them in parallel. But bound the fan-out. If you’re calling 8 services in parallel, set a hedged timeout — not “wait for all of them,” but “wait until 95% respond and use degraded data for the rest.” This is called partial responses or timeout hedging, and it’s a powerful pattern for high-availability systems.

// Example: parallel fetch with timeout and partial result tolerance
func fetchWithTimeout(ctx context.Context, services []ServiceClient, budgetMs int) []Result {
    ctx, cancel := context.WithTimeout(ctx, time.Duration(budgetMs)*time.Millisecond)
    defer cancel()

    results := make([]Result, len(services))
    var wg sync.WaitGroup

    for i, svc := range services {
        wg.Add(1)
        go func(idx int, client ServiceClient) {
            defer wg.Done()
            res, err := client.Fetch(ctx)
            if err != nil {
                results[idx] = Result{Degraded: true} // Use fallback
                return
            }
            results[idx] = res
        }(i, svc)
    }

    wg.Wait()
    return results
}

4. Cache aggressively and correctly

Not “add Redis in front of everything,” but cache at the right layer:

  • In-process cache for data that rarely changes: feature flags, configuration, rate limit thresholds. This eliminates the hop entirely.
  • Distributed cache (Redis, Memcached) for data that changes moderately and is expensive to recompute. But remember: a Redis call is still a network hop. Measure it.
  • CDN or edge caching for responses that are fully cacheable. The fastest hop is the one that never reaches your origin.

5. Tune your connection pools aggressively

Connection pool exhaustion is one of the most common causes of sudden latency spikes in production. When a pool is exhausted, new requests queue waiting for a connection — and that queueing can spike your p99 into seconds even when the underlying service is healthy.

For every downstream HTTP client in your system, explicitly configure:

  • Maximum connections
  • Connection timeout (how long to wait for a connection from the pool)
  • Request timeout (how long to wait for a response)
  • Idle timeout (how long to keep an unused connection alive)

Most HTTP client libraries default to conservative settings that are badly mismatched for high-throughput internal service calls.

6. Profile your serialization

Particularly in JVM-based and Node.js services, JSON serialization of large objects is surprisingly expensive. If you’re serializing the same data structure on every request, consider:

  • Pre-computing and caching the serialized form
  • Switching to Protobuf or MessagePack for internal APIs
  • Trimming your response payloads — only send what the caller actually uses

The Architectural Checklist

Before you ship any change that adds a new service call to a latency-sensitive path, run this checklist:

  • [ ] Measured the baseline latency of the new dependency (p50, p95, p99) in production or under realistic load
  • [ ] Calculated the new compound p99 for the full request chain after adding this hop
  • [ ] Verified the new p99 is within the latency budget with margin for growth
  • [ ] Considered async alternatives: can this happen outside the request path?
  • [ ] Set an explicit timeout on the call — not a default, a deliberate number based on the budget allocation for this hop
  • [ ] Defined a fallback for when this call fails or times out — degraded response, cached result, default value
  • [ ] Added tracing instrumentation so this hop appears in distributed traces
  • [ ] Added latency alerting on this specific service-to-service call at p99
  • [ ] Reviewed retry policy — retries are multiplied against the timeout; have you budgeted for them?
  • [ ] Checked connection pool settings — are they tuned for the expected concurrency of this call?
  • [ ] Reviewed if TLS/mTLS overhead has been measured and accounted for in the budget

If any of these items can’t be answered confidently, the PR should not merge into a latency-sensitive path without an explicit team discussion.

A Real Latency Budget Calculation

Let’s close the loop with a worked example you can adapt.

System: A mobile app backend. The product requirement is 150ms end-to-end response at p95 for the home feed endpoint.

Budget allocation:

Component Budget (p95) Owner
DNS + TCP + TLS (mobile to CDN edge) 10ms Infrastructure
CDN to origin gateway 5ms Infrastructure
Gateway + auth (JWT local validation) 5ms Platform
Feature flag resolution (local cache) 1ms Platform
Feed service business logic 30ms App team
Primary DB query (indexed read) 25ms App team
Recommendations service call 35ms ML team
Response serialization + compression 8ms App team
Return path network 10ms Infrastructure
Total allocated 129ms
Remaining headroom 21ms

This leaves 21ms of headroom before hitting the 150ms SLO. Now someone proposes adding a “personalization boost” service call. Its measured p95 is 18ms.

If you add it synchronously to the hot path, your headroom drops to 3ms. Any slight increase in traffic, any GC event in any service, any network hiccup — and you’re over budget. The right conversation is: “Can this call happen asynchronously? Can we pre-compute and cache the result? Does it need to be in the hot path?” Often the answer is no, it doesn’t.

This is how you defend your latency budget: with numbers, not intuition.

More Engineering Reads

If this kind of production-depth engineering writing is useful to you, more of it lives at kallis.in — a growing collection of engineering content covering system design, architecture, observability, and real-world development patterns.

The Takeaway

The problem with latency budgets isn’t that engineers don’t care about them. It’s that the damage is cumulative, invisible at the median, and always attributed to “the system getting more complex” rather than the specific architectural decisions that caused it.

One extra hop is never just 5ms. It’s 5ms at p50, and it’s the entire tail distribution of that service — including its worst-day behavior — injected into every request that goes through it. Multiply that across five services added over six months, and you’ve turned a snappy product into something that users feel is “kinda slow sometimes.”

The tools to fight this aren’t exotic. Distributed tracing, explicit budget allocation, p99 alerting, aggressive timeout tuning, and a cultural habit of treating every new synchronous hop as a cost that needs justification. That’s it.

Your architecture diagram shows boxes and arrows. Your users experience latency distributions. Make sure someone on your team is closing the gap between those two views — before your p99 starts closing it for you.

#performance #distributedsystems #systemdesign #backend #architecture #microservices

From Zero to Crypto Hero (Week 4) – Week of Break from Coding and Big Regret

luftietheanonymous profile

Hello Dev.to Community

This time I’m writing the article one day later, as I usually kept to push the updates to appear regularly on sunday. Well today is monday, so I guess it’s not a big deal 😅 (Especially coz mostly my posts do not make big outreach). Anyways, promise is a promise, thus I upload this tiny update on my work.

Are you ready ? Let’s go !

Introduction

So if I said, that I took break from coding, it means I’ve been buggering around, doing nothing and I just post it to just keep the streak ? Well technically correct 😀

Thanks for reading, I hope you enjoyed this part, don’t forget to hit a like or some other cool emoji and till next time. See ya !

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Ok, I was joking 🤣. If you’re still here to read further, congrats your curiosity is out of space 🚀.

This week perhaps was not filled a lot of with coding/programming whatsoever. But for sure it was not boring or completely wasted time.

So what have I been doing throughout this week ?

Let’s start with the fact, that I’ve been 3 days out and about in Warsaw on the conference Next Block Expo, specially devoted to cryptocurrencies but discussed from financial angle. I have shared more of my views on the event in that article (If you’re interested go on and read it)

As I reached my home-town and woke-up the next day, I honestly felt as though someone would have completely stolen my batteries🪫

In general, I liked the event from the point of view, that there were more projects that were genuinely interesting me than on the last edition, however here are yet couple of inferences that came into my mind. Not only about

Inferences

I’m not a fan of big cities

warsaw

I know in previous article I have written, that I do not like big cities, but that was very general statement. I’ve written in the article that I hate big cities, I forgot to add that at least in Poland, but more on that later.

Before I start let’s define what is a big city (at least for me) ? A big city at least for me is a agglomeration in which live 500k+ people (incld. commute-workers + students).

Although I personally do not live in some hicksville, I used to say so about place where I live. Warsaw felt for me like rotten, toxic and fake. I felt more endangered than even in Berlin tbh, whereas Berlin got the most unliked city in my hierarchy.

And additionally the air-conditions in Warsaw seemed awful to me (However I’m kind of over-sensitive in this case, so I might be biased). I mean indeed, the centre, accompanied by skyscrapers is looking nice and the most popular places are impressive, but for me it was enough to see how the city looks like 2/4/6 km away from the highlight-spots, to realise that Warsaw’s beauty is only marketing (as always lol).

It’s actually quite common in Poland, but I guess every city has it’s issues, regardless of the country. I remember back 2023, as I gone for my first ever solo-trip to Manchester, England. I’ve been there for about 4 days, back then I really didn’t experience something that would be hideous in some way, except a hobo, who pissed on a wall while I’ve been walking through the city, seeking a place to purchase a ticket for public-transport.

I admire always England for their infrastructure and architecture, when it comes to metropolis like Greater Manchester. I always laughed that Manchester is smaller than my city, but then I realised that the cities fade between each other and I remember that I could not realise if I’m in Salford/Trafford or Manchester. So were my experiences at least.

The World is centralized, not by government, by technology:

Sorry, I had no clue how to name this inference lol. I want to tell about my experience in Warsaw that indeed, was very mixed because I had kind of emergency situation. I haven’t taken the phone-charger to my phone, although before leaving the house I had been plugging in the power-bank to pack it into backpack.

Unfortunately both power-bank and charger have been left at home by the time of my departure. Unluckily, my phone’s battery’s level was decreasing rapidly, like never before.

And I was looking for place where to purchase a charger and I had impression that almost everything is against me. Suddenly some arab-guy and afterwards a hobo wanted to scrounge money from me and as I gone to the mall by bus, there was some shady-guy following me weirdly as though he wanted to pick-pocket me or something, he resigned after I have shown him a pepper-spray in my hand, not having even made an eye-contact with that guy.

I gone to a first mall and the charger cheapest charger was 100 PLN, it was Media-Markt shop. I asked the assistant, if can help me choose some cheap charger, and shockingly he advised me to go to the mall on the other side of the street to buy a charger in a supermarket.

The price there ? 18.50 PLN (for cable and the charger-cube) ! Whereas the cable at Media-Markt its-self was 79 PLN ! Can you comprehend it ? There is more 500% spread between price in special IT-RTV-AGD Shop and Super-market. It just blew my mind, honestly speaking and would never say it was reality.

I almost burst in tears when I have experienced the vibration of my phone going out of battery and me being not even with knowledge, where to purchase a charger.

What I meant by centralisation is that everything nowadays is heavily based on electronics and current/electricity. Perhaps that’s another problem to be solved, huh ? I know it’s my fault in the end of the days, that I hadn’t taken the charger 😅. I do not seek for excuses.

Small events > Big events: I reckon smaller events that are highly technical or devoted specifically for specific topic, are better than big events, where there are a lot of people. Big events tend to be more general and kind of discombobulating, as there are so many people talking to each other one has an impression to be a weirdo, not having talked to anyone.

Ferrari

Cybertruck

Big events have also a flaw, that there is very intrusive and pressure-full marketing done and on one day you can buy the same ticket for 65$ and the next day you can have 2 tickets in the same price, which is annoying. Smaller events often have stable price of the event-ticket, which I find a great solution, even if for someone it out of budget.

However for sure good things about big-events is bigger amount of projects and companies to be approached and talked to, to know what services are nowadays offered on the market.

And therefore, the amount of stickers is also greater 😀 Here’s the new layout/design of my laptop. Hope you like it 😁

sticker-filled

front-case

Whereas smaller events like for sure Monero Konferenco could be such event……

Unfortunately, I guess I will not be able to get to the event, due to the financial circumstances on my own. Now, I’ve an impression as though I wasted my money on NBX to be honest, although there are visible benefits from that event.

I really would love to visit Monero Konferenco this year’s edition (even though it’s in Warsaw). This event is going to be technical and specific, something I had dreamt about and could not find so specifically. It sounds it’s not going to be sort of scattered gibberish about financial matters.

Don’t get me wrong, finances are super-important field of human-life, but when it comes to such events, it ends up on artificially looking for me severe talks about the future, another 101 sessions instead of bringing some more medium-advanced/advanced knowledge so people can develop.

And unfortunately a lot of speakers in my eyes are just dreams-sellers and are excluded from reality, pushing from the stage some truisms about hard-work, persistence, everything everyone knows about. But in the end of the days, everyone has to deal with their own issues and do everything what they can in their scale to solve them, not in the speaker’s scale.

politics

Furthermore, I do not preach that big-events, are bad and you should not attend them. No I just present the trade-offs of both types of events. Both have pros and cons, that should be basically taken into a count and should be treated separately and not as a comparing-pair.

I have to confess, even though there were projects that interested me like Gen6, Relocatify or Sealed. Most of the projects were already about combining Tradfi with Defi. Speaking outspoken, that hurts. Cryptocurrencies were the hope, which were about to turn the way we understand finances and the way we pay. Unfortunately, it seems that cryptocurrencies become only an asset instead of what their real purpose was. It seems crypto became alternative and is not going to become a payment-system. At least not in next 5/10 years, I suppose.

tradfi

tradfi2

tradfi3

That doesn’t mean however that I stopped being engaged in cryptocurrencies and blockchain. No, I just know that I’m just likely to build a very niche product if I were to build a private-blockchain and it will not be something that institutions would put money into (Which I actually would not like them to do).

We saw how big pump was on ZTrash (ZCash) and even bigger dump occured, only to pump the narrative and take the money from naive people, who blindly believed in privacy-turn. Unless markets are controlled by big whales, that operate in fiat, psychotically indulge theirself in seeing wars and blood of other innocent people, and understand only money-language, no change in financial-system is about to occur, and people will exist, so long will the markets be manipulated.

Resign from my privacy standard was a failure – On NBX, I came to a conclusion, not to cover my face as I usually do in public and not only. I did it for common convenience and not to trigger controversies among people there (usually a covered face is associated mostly with criminals, than carrying about privacy). Also as I got to the venue, it turned out light was shit and the air was slightly humid for me, so I could suffocate in the mask and could basically fall on someone or cause damage while walking, if I had my glasses on.

Also I gone there with an attitude that, if I don’t show my face in social media anywhere, so I will not be recognisable by anyone (Previously I used to post my images in a mask online).

Big events have their flaw also that there are basically cameras everywhere, everyone is recording something and I genuinely felt, when I was just resting after networking as though someone would basically put the camera right into my face. Whereas MoneroKonferenco seems to be a really private arrangement. They have even their Photo Policy, which sound like:

Ask before snapping, all persons in a photo/video must have explicitly given consent to be photographed/recorded. As such, please avoid taking photos/video of large crowds, audience, or workshop participants.

Don’t get me wrong, I’m not saying those all fluffy stuff about that conference, trying to scrounge money from you guys or something, no.

Rather just express my genuine willingness to appear, there though given my financial situation I know it will be tough. I will not create a fund-raising for a trip to Warsaw specifically for Monero-Konferenco, if I cannot even give you anything in exchange.

One option would be to go and work there as an volunteer, as they get the ticket for free. Which sounds as an interesting experience in my opinion, we will see if the event will fit my schedule or not.

People on the big-events: I was surprised, when I saw people who have less knowledge about cryptocurrencies than I have, are younger than me, and make money in this industry, whereas I, not being fake-modest have a quite big knowledge on cryptocurrencies both from financial and technical point of view and haven’t made a single penny.

I do not complain or say I’m worse, just assert the facts that some people make money faster.

Candidly, I’m more looking on events for connecting with devs and people who build and also people who worked on projects already, than financial or businessman connection.

I decided to resign from hackathon participation

Given the fact that my financial struggle nowadays and my experience from trips, I decided not to participate in ETHSilesia hackathon, that I intended to.

Apparently everything seemed to fit in time perfectly, but the budget doesn’t lie and I cannot pump it somehow out of nowhere. My investments currently are 60% down, and I will not resolve the loss.

Hence, I decided to devote this time to implement solid gameplay feature with reward system based on ZKP (likely to be implemented with Noir).

Was there something technical, that I’ve done ?

Obviously ! Week without going is lost week though 😀 (Don’t take it literally). On Sunday/Monday I started implementing the gameplay functionality with socket.io and was fixing the bugs with the actual frontend code in my Pokestake project, that I work on.

You can see above the mechanism, that the connection between two players, has been successfully estabilished.

If you have some suggestions, feel free to visit my repos and create an issue with your suggestion 😀 If you see some bug or see a way to make code more efficient, also feel free to post an issue

Frontend

GitHub logo

LuftieTheAnonymous
/
PokeStake-Dapp

A Pokemon themed staking protocol with usage of Chainlink VRF

PokeStake 🎴⛓️

PokeStake Banner

A decentralized staking protocol where you can lock Pokemon cards and draw random rewards daily. Built on-chain with verifiable randomness and IPFS storage.

Overview

PokeStake is a Web3 staking protocol that lets users stake Pokemon cards and participate in daily random draws. Each day, stakers can claim a random card from the pool—powered by Chainlink VRF for cryptographically secure randomness and Pinata for decentralized card metadata storage.

Tech Stack

Technology Purpose Version
Next.js Frontend framework & API routes Latest
TypeScript Type-safe development Latest
Solidity Smart contract logic ^0.8.0
Foundry Smart contract development & testing Latest
RainbowKit Wallet connection & UI Latest
Wagmi Ethereum hooks & contract interaction Latest
TanStack Query Server state management Latest
Chainlink VRF Verifiable randomness v2
Pinata SDK IPFS pinning & card metadata Latest

Features

  • 🎴 Stake Pokemon Cards – Lock your cards into the protocol
  • 🎰 Daily Random Draws – Once per day, draw…

Smart-Contracts

GitHub logo

LuftieTheAnonymous
/
PokeStake_Protocol

A Staking protocol with usage of Chainlink VRF for drawing a random pokemon Card

Foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.

Foundry consists of:

  • Forge: Ethereum testing framework (like Truffle, Hardhat and DappTools).
  • Cast: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
  • Anvil: Local Ethereum node, akin to Ganache, Hardhat Network.
  • Chisel: Fast, utilitarian, and verbose solidity REPL.

Documentation

https://book.getfoundry.sh/

Usage

Build

$ forge build

Test

$ forge test

Format

$ forge fmt

Gas Snapshots

$ forge snapshot

Anvil

$ anvil

Deploy

$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>

Cast

$ cast <subcommand>

Help

$ forge --help
$ anvil --help
$ cast --help

Backend Code

How have you been doing ?

What were you up to in recent week ? Some event attended ? Some side-project done ? Some wins ? Some failures ? Let me know down in the comments, hope you reading enjoyed the article (I have edited and written it about 7 hours).

Cheers for reaching until the end, Luftie

ABAP Unit Testing in SAP S/4HANA: A Senior Architect’s Guide to Writing Tests That Actually Matter

Let me be honest with you: for most of my early career, ABAP unit testing felt like a box-ticking exercise. Write a test, make it green, move on. It wasn’t until I inherited a legacy codebase that kept breaking in production—in ways nobody could predict—that I truly understood what good unit tests are worth. If you’re serious about building ABAP unit testing practices that create real safety nets, this guide is for you.
We’re going to go well beyond the basics. We’ll look at test doubles, dependency injection in ABAP OOP, how to structure test classes for maintainability, and how to integrate testing into your development workflow in a way that actually sticks—without slowing your team to a crawl.

Why ABAP Unit Testing Is More Critical Than Ever in S/4HANA

S/4HANA migration projects are exposing years of technical debt. I’ve seen it repeatedly: a business-critical program that “works fine” on ECC gets migrated, and suddenly edge cases that were hidden for a decade start surfacing. Without a solid test suite, every change becomes a leap of faith.

Beyond migrations, the modern ABAP landscape has shifted dramatically. Clean ABAP principles (which we explored in ABAP Clean Code: 10 Golden Rules for Readable and Maintainable SAP Code) demand testability as a first-class concern. You can’t write clean code without writing testable code—they’re the same discipline.

Here’s the business case in plain terms:

  • Reduced regression risk: Catch breaking changes before they reach production

  • Faster onboarding: Tests document intent better than comments ever will

  • Refactoring confidence: Modify code without fear when your test suite has your back

  • Technical debt visibility: Hard-to-test code is a direct indicator of poor design

The Anatomy of a Good ABAP Unit Test

Before we write a single line, let’s align on what makes a unit test valuable. I use the FIRST principles as my mental checklist:

  • Fast — Runs in milliseconds, no database round-trips

  • Independent — Each test stands alone, no shared state

  • Repeatable — Same result every time, regardless of environment

  • Self-validating — Pass or fail, no manual inspection needed

  • Timely — Written close to (or before) the production code

Most ABAP unit tests I’ve audited fail on “Fast” and “Independent” because they hit the database or depend on system configuration. We’ll fix that.

Setting Up Your Test Class: The Local Test Class Pattern

ABAP unit tests live in local test classes defined in the test include of a global class, or directly in a program’s test include. Here’s the standard scaffold I use:


&quot;! @testing ZCL_ORDER_VALIDATOR
CLASS ltc_order_validator DEFINITION
  FOR TESTING
  RISK LEVEL HARMLESS
  DURATION SHORT.

  PRIVATE SECTION.
    DATA: mo_cut TYPE REF TO zcl_order_validator.  &quot; CUT = Class Under Test

    METHODS:
      setup,          &quot; Runs before each test method
      teardown,       &quot; Runs after each test method
      should_reject_empty_order         FOR TESTING,
      should_accept_valid_order         FOR TESTING,
      should_reject_order_over_limit    FOR TESTING.

ENDCLASS.

CLASS ltc_order_validator IMPLEMENTATION.

  METHOD setup.
    mo_cut = NEW zcl_order_validator( ).
  ENDMETHOD.

  METHOD teardown.
    CLEAR mo_cut.
  ENDMETHOD.

  METHOD should_reject_empty_order.
    &quot; Arrange
    DATA(ls_order) = VALUE zs_order( ).

    &quot; Act
    DATA(lv_result) = mo_cut->validate( ls_order ).

    &quot; Assert
    cl_abap_unit_assert=>assert_equals(
      act  = lv_result
      exp  = abap_false
      msg  = &#039;Empty order should be rejected&#039;
    ).
  ENDMETHOD.

  METHOD should_accept_valid_order.
    &quot; Arrange
    DATA(ls_order) = VALUE zs_order(
      order_id   = &#039;4500001234&#039;
      material   = &#039;MAT-001&#039;
      quantity   = 10
      unit       = &#039;PC&#039;
    ).

    &quot; Act
    DATA(lv_result) = mo_cut->validate( ls_order ).

    &quot; Assert
    cl_abap_unit_assert=>assert_equals(
      act  = lv_result
      exp  = abap_true
      msg  = &#039;Valid order should be accepted&#039;
    ).
  ENDMETHOD.

  METHOD should_reject_order_over_limit.
    &quot; Arrange
    DATA(ls_order) = VALUE zs_order(
      order_id   = &#039;4500001235&#039;
      material   = &#039;MAT-001&#039;
      quantity   = 99999  &quot; Exceeds business limit
      unit       = &#039;PC&#039;
    ).

    &quot; Act
    DATA(lv_result) = mo_cut->validate( ls_order ).

    &quot; Assert
    cl_abap_unit_assert=>assert_equals(
      act  = lv_result
      exp  = abap_false
      msg  = &#039;Order exceeding quantity limit should be rejected&#039;
    ).
  ENDMETHOD.

ENDCLASS.

Notice the naming convention: should_[expected_behavior]_[when_condition]. This reads like a specification. When a test fails at 2am, you want the name to tell you exactly what broke—not force you to dig through code.

Dependency Injection: The Key to Testable ABAP OOP Code

Here’s where most ABAP developers hit a wall. Your class calls a database-reading helper, an RFC, or a BAdI. How do you test the logic without actually hitting those external dependencies?

The answer is dependency injection—and it pairs perfectly with the OOP design patterns covered in ABAP OOP and Strategy Pattern: Real-World Applications.

Here’s the pattern in practice. First, define an interface for your dependency:


INTERFACE zif_material_repository.
  METHODS get_by_id
    IMPORTING iv_material_id TYPE matnr
    RETURNING VALUE(rs_material) TYPE mara
    RAISING   zcx_material_not_found.
ENDINTERFACE.

Then implement the real version that hits the database:


CLASS zcl_material_repository DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES zif_material_repository.

ENDCLASS.

CLASS zcl_material_repository IMPLEMENTATION.
  METHOD zif_material_repository~get_by_id.
    SELECT SINGLE * FROM mara
      WHERE matnr = @iv_material_id
      INTO @rs_material.
    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE zcx_material_not_found.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

Now inject the dependency through the constructor:


CLASS zcl_order_processor DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING io_material_repo TYPE REF TO zif_material_repository.

    METHODS process_order
      IMPORTING is_order        TYPE zs_order
      RETURNING VALUE(rv_success) TYPE abap_bool.

  PRIVATE SECTION.
    DATA mo_material_repo TYPE REF TO zif_material_repository.

ENDCLASS.

CLASS zcl_order_processor IMPLEMENTATION.
  METHOD constructor.
    mo_material_repo = io_material_repo.
  ENDMETHOD.

  METHOD process_order.
    TRY.
      DATA(ls_material) = mo_material_repo->get_by_id( is_order-material ).
      &quot; ... business logic here ...
      rv_success = abap_true.
    CATCH zcx_material_not_found.
      rv_success = abap_false.
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

Writing Test Doubles: Mocks, Stubs, and Fakes in ABAP

With dependency injection in place, you can now inject a fake implementation during testing. Let’s create a test double for our material repository:


&quot; Define inside the test class include
CLASS ltc_material_repo_stub DEFINITION FOR TESTING.
  PUBLIC SECTION.
    INTERFACES zif_material_repository.
    DATA ms_return_material TYPE mara.
    DATA mv_should_raise     TYPE abap_bool.
ENDCLASS.

CLASS ltc_material_repo_stub IMPLEMENTATION.
  METHOD zif_material_repository~get_by_id.
    IF mv_should_raise = abap_true.
      RAISE EXCEPTION TYPE zcx_material_not_found.
    ENDIF.
    rs_material = ms_return_material.
  ENDMETHOD.
ENDCLASS.

&quot;! @testing ZCL_ORDER_PROCESSOR
CLASS ltc_order_processor DEFINITION FOR TESTING
  RISK LEVEL HARMLESS
  DURATION SHORT.

  PRIVATE SECTION.
    DATA: mo_cut       TYPE REF TO zcl_order_processor,
          mo_repo_stub TYPE REF TO ltc_material_repo_stub.

    METHODS:
      setup,
      should_succeed_when_material_found    FOR TESTING,
      should_fail_when_material_not_found   FOR TESTING.

ENDCLASS.

CLASS ltc_order_processor IMPLEMENTATION.

  METHOD setup.
    mo_repo_stub = NEW ltc_material_repo_stub( ).
    mo_cut = NEW zcl_order_processor( mo_repo_stub ).
  ENDMETHOD.

  METHOD should_succeed_when_material_found.
    &quot; Arrange: Configure stub to return a valid material
    mo_repo_stub->ms_return_material = VALUE mara( matnr = &#039;MAT-001&#039; ).
    mo_repo_stub->mv_should_raise = abap_false.

    &quot; Act
    DATA(ls_order)   = VALUE zs_order( material = &#039;MAT-001&#039; quantity = 5 ).
    DATA(lv_success) = mo_cut->process_order( ls_order ).

    &quot; Assert
    cl_abap_unit_assert=>assert_true(
      act = lv_success
      msg = &#039;Order processing should succeed when material exists&#039;
    ).
  ENDMETHOD.

  METHOD should_fail_when_material_not_found.
    &quot; Arrange: Configure stub to simulate missing material
    mo_repo_stub->mv_should_raise = abap_true.

    &quot; Act
    DATA(ls_order)   = VALUE zs_order( material = &#039;GHOST-MAT&#039; quantity = 5 ).
    DATA(lv_success) = mo_cut->process_order( ls_order ).

    &quot; Assert
    cl_abap_unit_assert=>assert_false(
      act = lv_success
      msg = &#039;Order processing should fail when material does not exist&#039;
    ).
  ENDMETHOD.

ENDCLASS.

No database. No RFC calls. These tests run in under 10 milliseconds, and they prove exactly what you need them to prove.

Testing Exception Handling: Don’t Skip This

One of the most overlooked aspects of unit testing is verifying that your exception handling logic—which we explored deeply in ABAP Exception Handling: Clean, Reliable Error Management—actually works as designed. Here’s how to assert that an exception is raised:


METHOD should_raise_exception_on_null_input.
  DATA lx_exception TYPE REF TO zcx_invalid_input.

  TRY.
    mo_cut->process_order( VALUE #( ) ).
    &quot; If we reach here, the test should fail
    cl_abap_unit_assert=>fail(
      msg = &#039;Expected ZCX_INVALID_INPUT to be raised but it was not&#039;
    ).
  CATCH zcx_invalid_input INTO lx_exception.
    &quot; Assert the exception carries the right message
    cl_abap_unit_assert=>assert_not_initial(
      act = lx_exception->get_text( )
      msg = &#039;Exception should carry a meaningful message&#039;
    ).
  ENDTRY.
ENDMETHOD.

Common Pitfalls to Avoid

I’ve reviewed hundreds of ABAP test suites. Here are the mistakes I see most often:

1. Testing Implementation, Not Behavior

Your test should answer “does this method do what I expect?” not “does this method call these internal methods in this order?” If your tests break every time you refactor internals, they’re testing the wrong thing.

2. One Giant Setup Method

When your setup method tries to configure everything for every possible test scenario, tests become impossible to understand. Instead, create helper methods that each test can call to set up only what it needs.

3. Magic Numbers Without Explanation

Why is the quantity limit 99999? Document it. A test is documentation first, verification second.

4. Ignoring the Risk Level Annotation

Use RISK LEVEL HARMLESS for pure unit tests. If a test really does need database access (for integration-style tests), set it to CRITICAL and separate it from your unit test suite. Mixing them destroys your fast feedback loop.

Integrating Unit Tests Into Your Development Workflow

Writing tests is only half the battle. The other half is making sure they actually get run. Here’s the workflow I recommend for teams:

  • Run unit tests before every transport release — Use transaction SE80 or ABAP Development Tools (ADT) in Eclipse to run tests for all affected objects

  • Set a code coverage target — I recommend starting at 60% and moving toward 80% over time. Perfect coverage is a myth; meaningful coverage is the goal

  • Use ATC (ABAP Test Cockpit) rules — Configure ATC to flag objects that have zero test coverage as a code quality warning

  • Review test code in code reviews — Test code is production code. It deserves the same scrutiny

  • Never skip tests to meet a deadline — This is the most expensive shortcut in software development

Quick Reference: Key cl_abap_unit_assert Methods

Method
Use When

assert_equals
Exact value match expected

assert_not_equals
Value must differ from unexpected

assert_true
Boolean condition must be true

assert_false
Boolean condition must be false

assert_initial
Variable must be initial/empty

assert_not_initial
Variable must have a value

assert_bound
Reference must not be null

assert_not_bound
Reference must be null

fail
Force a test failure unconditionally

Final Thoughts: Tests Are a Design Activity

The best insight I can offer after years of working on SAP systems is this: if your code is hard to test, your design has a problem. Testability is a forcing function for good architecture. The moment you try to write a unit test and realize you need to spin up half the SAP system to do it, that’s feedback—feedback that your class is doing too much or knows too much about its surroundings.

Start small. Pick one class, write three meaningful tests for it. See how it feels. Then expand. The habit, once formed, is genuinely one of the most valuable professional skills you can build as an ABAP developer.

And if you’re working on the performance side of things—making your ABAP code not just correct but fast—make sure to check out SAP ABAP Performance Optimization: Identifying and Fixing Bottlenecks in Real-World Systems. Tests and performance go hand in hand: you can’t safely optimize code you haven’t tested.

What’s your current testing setup look like? Are you starting from zero, or trying to add tests to an existing codebase? Drop a comment below—I read every one, and real-world questions often turn into future articles. If this was useful, share it with a colleague who’s still shipping code without tests. 🙂