runtimeanalyz.ing

← All capabilities

prod_dead_api

MCP · CLI Pro

Public methods no app run called. The public methods that no recorded app run calls. It counts request and job trees and leaves spec trees out, so a call from a method's own spec does not count as a caller.

ReportsController 214 deploys
quarterly_totals
via public_send · 412 calls
Report
class Report
  def quarterly_totals = …
  def legacy_totals = …
end
nothing 91 days of prod
legacy_totals
never reached
Pooled 38.2M production call trees · every deploy, every server, one graph
In a local recording neither method has a caller. In pooled production traffic, quarterly_totals is reached through public_send every day and legacy_totals has no caller. The counts in this picture illustrate pooled production traffic, which needs the hosted graph. The output below is from the example app.

The problem

dead_api lists Report#legacy_totals as having no caller in any recorded run. That is not proof that the method is unused, because your suite doesn’t run the month-end rake task, the admin export, or the webhook a partner hits twice a year. Any of them might call legacy_totals, and grep does not show whether they do. This is app/controllers/reports_controller.rb in the example app:

class ReportsController < ApplicationController
  def show
    report = Report.new(params[:account_id])
    render plain: report.public_send("#{params[:kind]}_totals").to_s
  end
end

"#{params[:kind]}_totals" becomes a method name at runtime, so nobody can prove from the source that legacy_totals is safe to delete. The method stays, and it is tested, documented and kept through every refactor.

The fix

ra prod_dead_api asks the same question of the app runs, with spec trees left out:

$ ra prod_dead_api app/models/report.rb
prod_dead_api app/models/report.rb
· pooled from 2 recorded runs · 150 app-run trees
Report#initialize  2 app-run callers: ReportsController#show 31 calls, DashboardController#show 30 calls
· Report#legacy_totals: no app-run caller
  app/models/report.rb:6
  → safe to delete
Report#quarterly_totals  1 app-run caller: ReportsController#show via public_send 31 calls
· Report#csv_rows: no app-run caller
  app/models/report.rb:14
  → only spec callers
  … rows, build, render and footer_text, each with spec callers only
Report#summary_line  1 app-run caller: Report#summary 62 calls
Report#summary  1 app-run caller: DashboardController#show 31 calls

quarterly_totals looked equally dead locally, and the app runs show a controller reaching it through public_send 31 times. legacy_totals had no caller in any run or from any entry point. Delete it:

class Report
  def quarterly_totals = totals_for(:quarter)
  def csv_rows = rows.map(&:to_csv)
end

How it works

The recorder wraps every method your app defines, so a call is recorded however it was made: directly, through send or public_send, from a callback or from a name built out of a string. Every call tree is stamped with its entry point, so the tool sets aside the trees from spec examples and counts the request and job trees.

prod_dead_api lists each public method in the file, from the source, with its app-run callers. A method with none is flagged, and the report says whether specs called it, so you know to delete those specs along with the method.

Two additions are planned. One is pooling the recordings of every deploy into one hosted graph, so that the summary counts deploys and days where it now counts two recorded runs. The other is a “last called” column, which needs timestamps the recorder does not write yet.

Run it on your app

The output on this page comes from our example Rails app, and it is regenerated whenever a tool changes. These are the commands behind it. On your own app, run ra record first, then put your own class, method or file in their place.

ra prod_dead_api app/models/report.rb

The dead method is app/models/report.rb:6, and the public_send is app/controllers/reports_controller.rb:4.

Reading the result

  • The evidence covers the period you recorded. A method called once a year needs a year of recording to be seen, and the report says how many runs and trees it pooled.
  • It sees the processes you record. A worker fleet or a service that you did not run under the recorder can still call a method that nothing else calls.

Every tool reads the same recording. What gets recorded and how far to trust an answer are on the questions page.

dead_api

LSP · CLI Pro

Find dead public API. The public methods that no caller reached in any recorded run, including those whose only caller is their own spec. Shown as a hint in your editor.

See more →

what_calls

CLI · LSP · MCP free

The callers of a method. Every caller of a method in the recorded runs, with the file and line of each call and how often it was made, including calls made through public_send. what_it_calls lists the methods it calls.

See more →

coupling_map

CLI · MCP Pro

Coupling measured from app runs. Which modules and namespaces of your app call each other, and how many times, counted from recorded app runs.

See more →