惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
O
OpenAI News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
Webroot Blog
Webroot Blog
GbyAI
GbyAI
S
SegmentFault 最新的问题
Cyberwarzone
Cyberwarzone
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
J
Java Code Geeks
Google DeepMind News
Google DeepMind News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 【当耐特】
S
Secure Thoughts
酷 壳 – CoolShell
酷 壳 – CoolShell
AWS News Blog
AWS News Blog
Engineering at Meta
Engineering at Meta
S
Security Affairs
H
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
D
DataBreaches.Net
云风的 BLOG
云风的 BLOG
Hugging Face - Blog
Hugging Face - Blog
Google DeepMind News
Google DeepMind News
Spread Privacy
Spread Privacy
T
Threatpost
Forbes - Security
Forbes - Security
C
Cisco Blogs
Scott Helme
Scott Helme
Attack and Defense Labs
Attack and Defense Labs
Simon Willison's Weblog
Simon Willison's Weblog
腾讯CDC
The Last Watchdog
The Last Watchdog
Cloudbric
Cloudbric
Last Week in AI
Last Week in AI
Recorded Future
Recorded Future
小众软件
小众软件
V
Vulnerabilities – Threatpost
美团技术团队
人人都是产品经理
人人都是产品经理
有赞技术团队
有赞技术团队
Apple Machine Learning Research
Apple Machine Learning Research
Hacker News - Newest:
Hacker News - Newest: "LLM"
I
Intezer
月光博客
月光博客
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园 - 司徒正美
C
Cybersecurity and Infrastructure Security Agency CISA
Martin Fowler
Martin Fowler
博客园 - 聂微东

Graphite blog

Introducing Code Tours: a new way to review Introducing Cursor Cloud Agents in Graphite Building the future of software development with Cursor Reimagining the PR Page: Designing for speed and focus Graphite changelog [11-20-2025] Graphite changelog [11-04-2025] Graphite changelog [10-16-2025] The future of engineering is collaborative (and already here) Meet Graphite Agent: the next evolution of AI code review Introducing frozen branches: A safer way to build on your teammates’ work Graphite changelog [09-17-2025] How we sped up code search for Graphite Chat Introducing Graphite Chat AI is writing code—here's why it also needs to review that code How I got Claude to write code I could actually ship How we built the first stack-aware merge queue (and why it matters) How we organize our monorepo to ship fast Graphite brings stacking to Tower Code review tooling: Should you build or buy? Making AI code review available to everyone Introducing: The new Graphite + Linear integration Graphite raises $52M and launches Diamond to reimagine code review for the age of AI Why AI will never replace human code review How stacked PRs unblock distributed development teams Graphite is going to Developer Week 2025 Beating the end of year code freeze How Graphite’s eng team ships code remarkably fast Why we chose Anthropic's Claude to power Graphite Reviewer AI code generation will remain fragmented How we redesigned Graphite's landing page in-house Introducing Graphite Reviewer: your AI code review companion How AI code review reduces review cycles to improve developer productivity What if you could get instant feedback on your code? The new developer toolchain Not Rocket Science - How Bors and Google’s TAP inspired modern merge queues Graphite's State of code review 2024 How Google migrated billions of lines of code from Perforce to Piper Going from 0 to 1: How to write better unit tests when there are none Speed up your merges: Parallel CI is now generally available for teams using Graphite’s merge queue Down for less than four minutes a month: how AWS deploys code BitKeeper, Linux, and licensing disputes: How Linus wrote Git in 14 days Graphite is now free for startups and open source projects Launch week wrap-up (May 2024) Reduce CI costs for Buildkite and GitHub Actions Cheaper CI & faster merging with batching How Google does code review The technical learning curve at a startup is gentler than you might think Graphite will now automatically rebase your partially-merged stacks Multiple engineers can now seamlessly collaborate on the same stack of PRs Do you ever outgrow GitHub? From the 80's to 2024 - how CI tests were invented and optimized Graphite changelog [4/10/2024] 🎺 Graphite changelog [4/25/2024] 🐸 How Stack Overflow replaced Experts Exchange How GitHub monopolized code hosting Graphite changelog [3/27/2024] 🤝 The core principles of building a good AI feature Onboarding roulette: deleting our employee accounts daily Graphite changelog [3/13/2024] 🚁 Why Facebook doesn’t use Git How to recreate the Phabricator code review workflow Types of code reviews: Improve performance, velocity, and quality What's the best GitHub pull request merge strategy? Phabricator vs GitHub vs Graphite: How do they stack up? Improving team velocity through better pull request practices Moving fast breaks things: the importance of a staging environment Building trust as a software engineer Keeping code simple: moving fast by avoiding over-engineering What's better than GitHub pull request filters? The Graphite pull request inbox 7 Best Phabricator alternatives for PR stacking + code review [2024] Accurate eng estimations: predicting and negotiating the future Tracking and understanding GitHub PR stats: A step-by-step guide 8 pull request best practices for optimal engineering What’s next for Graphite Graphite Q1 Launch week: Stacking with the tools you love Graphite Q1 Launch week: Making stacking seamless Accelerating code review The Mom Test How to use stacked PRs to unblock your entire team Graphite Q1 launch week 2024 The practical and philosophical problems with AI code review Empirically sup code review best practices Every engineer should understand git reflog Post mortem: we took 124 seconds from you, here's 378 back Your GitHub pull request workflow is slowing everyone down Optimizing CI/CD workflows for trunk-based development Why we use AWS instead of Vercel to host our Next.js app How large pull requests slow down development 3 key lessons in application server optimization Trunk-based development: why you should stop using feature branches Git was built in 5 days Why large companies and fast-moving startups are banning merge commits How long should your CI take? Experimenting with AI code review CRA to AppRouter in 5 Steps: A case study with Graphite Graphite Changelog [10/18/2023] The comprehensive guide to writing the best PR title of all time How 10,000 Developers All Contribute to the same Repo
Call site attribution: how to pinpoint rogue SQL queries throttling your performance
Greg Foster · 2023-12-14 · via Graphite blog

As traffic and data grow, queries that were fast last week can suddenly cripple your app this week. Pinpointing exactly where these slow queries originate can be tricky, but achieving "call site attribution", identifying the exact point in the source code from where the SQL query is being executed, allows developers to find and fix performance bottlenecks quickly.

In this post, I'll walk through how we added call site attribution to our Node.js web app in anticipation of scaling our hundreds of millions of SQL queries a day, into billions. For this article, I interviewed Aryaman Naik, one of our engineers leading this database project, to do a deeper dive into our call site attribution process. Here are the key takeaways:

The problem: 10X database growth on the horizon

With our current user growth trends, we anticipate traffic could grow 10X from current levels. This is a good problem to have, but still requires preparation: mainly ensuring we prioritize infrastructure tasks, like database scalability, and make sure this work doesn’t slip through to the icebox. The last few months, our engineering team has been heads down building new features, and in that interim our DB usage crept up to nearly 40% capacity of AWS’ 4x large database. The largest machine AWS provides is a 16x large, meaning without optimizations, at 10x growth, we would hit the limits of the machines AWS can provide, and have to start looking into more complex problems like sharding Postgres writes or worst case, moving off Postgres entirely.

At this point, we realized: if traffic does grow 10X (as we’re predicting), we'll quickly hit a ceiling on our database utilization, grinding application performance to a halt. All this during a crucial period when an influx of new users are just evaluating Graphite for the first time.

In order to handle this expected surge in traffic and mitigate performance concerns, we needed to reduce SQL query load substantially. The first step in this process was identifying which queries were hogging resources. From there, we could trace those queries back to the originating code and optimize the worst offenders.

Easier said than done.

Attempted solutions: Datadog, sampling, and monkey patching

Our initial thought was to use Datadog to trace queries originating from HTTP requests, which we already had in place for general monitoring. But unfortunately, most of our load comes from background workers not directly tied to these requests, preventing Datadog from giving us any visibility into these queries.

We then explored a couple of other options:

  • Expand Datadog usage: Wrap every SQL query in a Datadog span, to provide tracing and attribution. While this would work in theory, it would also raise our Datadog spend by a factor of 100x, so this solution was quickly canned.

  • Monkey patching: Programmatically insert the call stack into each SQL query as a comment. The downsides here however were legibility and limitations with how to fetch the call stack, so this would not work either.

Ultimately, neither solution provided the desired end-to-end tracing from SQL to code, blocked by both cost and functionality.

The winning solution: call site tagging

The solution we ultimately implemented was to require all SQL queries to be tagged with a user-defined string indicating the call site. For example:

SELECT * FROM users WHERE id = 1

Now when we view slow queries, the call site tag instantly tells us where the query originated in our codebase.

Some key benefits of this approach:

  • Legibility: The tag is readable at a glance when viewing SQL queries.

  • Traceability: We can instantly jump to the tagged file in our codebase.

  • Grouping: Similar queries from the same part of the codebase can be grouped together, allowing us to identify problem areas more holistically.

  • Cost: No additional cost, unlike with Datadog tracing.

Once we settled on this solution however, there were some additional implementation challenges to work through.

Implementation challenges with TypeORM

One of the first challenges we ran into was the ORM we use in our Node.js/Postgres stack, TypeORM, only supports query tagging in some of its APIs. For example, the .create() and .find() methods can add tags, but not .update() or .delete().

Under the hood however, TypeORM uses a query builder to construct SQL queries, so we wrapped all TypeORM calls in the query builder API, then added tagging there. This took some work to replicate TypeORM's custom logic on top of the query builder, but eventually we were able to ensure every query was tagged with its corresponding call site.

We also added linting rules to prohibit use of any TypeORM APIs that couldn't support tagging, ensuring the use of our wrappers, and preventing our custom tagging logic from being bypassed.

Overall we were able to achieve nearly 100% coverage of all queries with call site tags. From here, we put together a dashboard and can now tell from a glance which parts of our codebase need optimization.

Key takeaways for your own project

Here are my key conclusions:

  • Don't shy away from ORM libraries like TypeORM: ORM’s provide immense productivity gains, however, don’t be afraid to examine multiple different offerings. Evaluate them based on your specific needs, as some are easier to implement out of the box, but are much more rigid in their functionality.

  • Add call site tagging from the beginning: Eventually as you scale, you’re going to need it when optimizing your database performance. Having visibility into performance early on helps you optimize along the way and prevents you from accumulating potential tech debt.

  • Ensure your ORM supports query tagging: Not all of them do, and this metadata is crucial.

Looking ahead

Call site tagging got us 95% of what we needed without a major overhaul of our data infrastructure. However, there are still opportunities for improvement:

  • Support tagging across all APIs called by TypeORM.

  • Include the line number along with the file name in each tag.

  • Build internal tooling preventing engineers from creating untagged queries, ensuring we maintain visibility into our database performance.

As a result of the increased visibility that call site optimization gave us, we were able to quickly identify and correct problem areas in our code base. As a result of these optimizations, we finally feel like we’re in a place where we can handle our predicted traffic increase. Of course, the work is never over, and we’ll continue to optimize and implement performance improvements as we scale our userbase from 10x, to 100x, to 1,000x, making blog posts along the way.