MyPerf4J: a JavaAgent APM for method-level latency on high-concurrency JVMs
High performance Java APM. Powered by ASM. Try it. Test it. If you feel its better, use it.
At a glance
- What is it?
- MyPerf4J attaches as a JavaAgent, rewrites bytecode with ASM, and writes per-method RPS and percentile statistics to log files. It is a narrow instrument for finding slow methods, not a tracing platform.
- Who is it for?
- Adopt MyPerf4J when you already suspect a specific service is slow and you want per-method RPS and TP99 without touching application code or running a collector. Do not adopt it if you need distributed traces, per-request context, or a queryable metrics store, because it writes to log files and offers no rollback beyond removing the agent flags.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 61 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem MyPerf4J targets: slow methods in a JVM you cannot easily modify
Most Java profiling starts with a problem you can already feel: a service that meets its SLA on average but spikes at p99, or an endpoint that got slower after a deploy. Attaching a sampling profiler answers some of that, but it gives you stacks, not per-method request counts with percentiles over a fixed window. Changing application code to add timers is usually off the table in production, and a full tracing stack is a large commitment when the question is narrower than "where did this request go".
MyPerf4J is built for that narrower question. The README states the project is "a high performance Java performance monitoring and statistics tool designed for high concurrency and low latency applications", and lists its value as locating performance bottlenecks and fault causes quickly. The intended user is a backend or SRE engineer who owns a JVM in production and wants method-level numbers without editing that application. It is not a request tracer, and it does not claim to be one.
JavaAgent plus ASM: how the method metrics actually get collected
The README states the tool is non-invasive and uses a JavaAgent, so no application code changes are required. The repository layout confirms the mechanism: MyPerf4J-ASM is a separate module, and the distributed artifact is named MyPerf4J-ASM.jar. Bytecode instrumentation is done with ASM, which the repository description names directly.
At startup the agent is loaded through -javaagent, and a second flag, -DMyPerf4JPropFile, points at a properties file. That file controls which packages get instrumented through filter.packages.include, what the application is called through app_name, and where output goes through metrics.log.xxx keys. Instrumentation is therefore scoped by package filter rather than applied to the whole classpath, which matters on a large application: the filter is the main lever you have over both overhead and noise.
The output is a plain text table written per statistics window. The README shows a window of one second and columns for Type, Level, TimePercent, RPS, Avg, Min, Max, StdDev, Count, TP50, TP90, TP95, TP99, TP999, TP9999 and TP100. The README also states the minimum statistics granularity is 1 second and that statistics are full, meaning no record is dropped. Two design claims sit behind that: the project states a single thread can record 16 million response times per second at 63 nanoseconds per record, and that memory reuse keeps temporary object allocation low so application GC is not disturbed. Those are the project's own figures from its wiki, not measurements made here.
Installing MyPerf4J and reading your first method_metrics.log
The README points at a zip rather than a package manager. Download and unpack MyPerf4J-ASM.zip, then edit the bundled MyPerf4J.properties. The README names three settings you must change: app_name, the metrics.log.xxx keys, and filter.packages.include. A properties file template is linked from the README for reference.
With the properties edited, add two JVM arguments. The README gives this exact form, and the JDK 9 and later note about --add-opens is part of the same instruction:
java -javaagent:/path/to/MyPerf4J-ASM.jar \
-DMyPerf4JPropFile=/path/to/MyPerf4J.properties \
--add-opens java.base/java.lang=ALL-UNNAMED \
-jar yourApp.jarStart the application and the metrics are written to the path you configured under metrics.log.xxx. The README's example output file is /path/to/log/method_metrics.log, and each block is headed by a window such as "MyPerf4J Method Metrics [2020-01-01 12:49:57, 2020-01-01 12:49:58]". Rows are per method, for example DemoServiceImpl.getId2(long) with Type General, Level Service, RPS 6524, Avg 0.49 ms and Count 6524. Read the TimePercent column first: in the sample it is the column that separates the methods consuming time from the ones merely being called often, and getId1(long) shows 0.00% despite the highest RPS in the table.
To remove the agent, the README says to drop the two JVM arguments and restart. There is no uninstall command and no runtime detach. For a build from source, the README gives git clone followed by mvn clean package, with the resulting MyPerf4J-ASM-${MyPerf4J-version}.jar placed in MyPerf4J-ASM/target/.
Where MyPerf4J stops: no traces, no request context, log-file output
The metrics are per method per time window. Nothing in the README describes a request or trace identifier, so you cannot follow one slow call through several services, and you cannot correlate a spike in one method with the user or endpoint that caused it. If your question is "which downstream call made this request slow", MyPerf4J is the wrong tool and a distributed tracer is the right one.
Output is a text log, not a metrics endpoint or a queryable store. The README's InfluxDB and Grafana path is documented in the wiki, and the JVM Metrics dashboard is linked to a Grafana dashboard ID, but the repository README itself only shows the log format. That means retention, rotation and disk usage are your problem. A metrics file written every second for a large filtered package set is not small, and the README does not document a built-in rotation policy, a size cap, or backpressure when the disk fills.
Two further constraints come from the mechanism. The package filter decides what is instrumented, so a filter that is too broad instruments framework and library code you do not care about, and one that is too narrow silently produces an empty or partial report. And because instrumentation happens through the JVM, the README notes that JDK 9 and later require --add-opens java.base/java.lang=ALL-UNNAMED; omit it and the agent does not work as documented. Rollback is a restart: the README's uninstall section is removing the two flags, so there is no way to disable collection on a running JVM without a restart.
MyPerf4J versus an OpenTelemetry-style tracing pipeline
The closest alternative for a team already doing observability is an OpenTelemetry agent feeding a collector and a backend. The difference is what gets recorded. A tracing pipeline propagates context across process boundaries and stores spans, so it answers questions about request paths, service dependencies and per-request latency breakdowns. MyPerf4J records no context at all; it aggregates response times per method inside one JVM and prints them. That makes it far cheaper to run and trivial to read, and it makes it structurally unable to answer cross-service questions.
A second alternative is a sampling profiler, which shows where CPU time goes inside a method rather than how long callers waited on it. MyPerf4J's Avg, Max and TP99 columns measure elapsed response time, including time blocked on I/O or a lock, so a method can look slow in MyPerf4J while the profiler shows it consuming almost no CPU. The two answer different questions, and the README's own framing (locating bottlenecks and fault causes) is about the response-time side.
There is also a deployment difference. A tracing pipeline needs a collector, storage and dashboards before it produces anything. MyPerf4J needs two JVM flags and a properties file, and its first useful output is a text file. That is the trade: less infrastructure, less reach.
Maintenance, licence and the cost of upgrading
The repository is not archived, and the last push was on 2026-07-31. Releases are not on a fixed cadence: 3.4.0 was published on 2024-09-08, 3.5.0 on 2025-10-18 and 3.6.0 on 2025-11-16. The gap between 3.4.0 and 3.5.0 is roughly thirteen months, so plan upgrades around releases rather than assuming a regular schedule.
Upgrade cost is low by construction. The agent is a jar plus a properties file, and the README's install and uninstall steps are both JVM argument edits. There is no schema migration and no server component to upgrade in lockstep. The real cost is the restart: the README documents no hot attach or detach, so any agent change is a JVM restart, which on a production service means a rolling deploy.
MyPerf4J is licensed under BSD-3-Clause. That is a permissive licence, and it is the licence file at the repository root. This is not legal advice; if you redistribute the agent inside a product, read the LICENSE file and the third-party licences of the bundled ASM dependency yourself.
Editorial conclusion
Adopt MyPerf4J when you already suspect a specific service is slow and you want per-method RPS and TP99 without touching application code or running a collector. Do not adopt it if you need distributed traces, per-request context, or a queryable metrics store, because it writes to log files and offers no rollback beyond removing the agent flags. Before rolling it out, verify three things on a staging JVM: that filter.packages.include actually matches your packages, that the JVM flag set includes --add-opens java.base/java.lang=ALL-UNNAMED on JDK 9 or later, and that your log rotation policy can absorb a metrics file that grows every second.
Frequently asked questions
What are the best monitoring tools for Java applications?
That depends on the question you are asking. MyPerf4J is a JavaAgent that collects per-method metrics such as RPS, Avg, Max and TP99 inside one JVM and writes them to log files, which suits latency work on a single service. If you need request paths across services, you need a tracing pipeline instead, because MyPerf4J records no request context.
Does MyPerf4J require changes to my application code?
No. The README states the tool uses a JavaAgent and is completely non-invasive, so application code is not modified. You add -javaagent and -DMyPerf4JPropFile to the JVM startup arguments instead.
How do I remove MyPerf4J from a running application?
You do not, at runtime. The README's uninstall instructions are to remove the -javaagent and -DMyPerf4JPropFile arguments and restart the JVM. There is no documented way to detach the agent from a live process.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/linshunkang-myperf4j)