kneed: finding the knee point of a curve in Python
Knee point detection in Python :chart_with_upwards_trend:
At a glance
- What is it?
- Kneed implements the Kneedle algorithm for detecting the point of maximum curvature in a set of x and y values, with automatic curve shape detection, an online mode for multiple knees, a tunable sensitivity parameter and built-in plotting. It is a small, dependency-light library that still expects you to decide what a knee means in your data.
- Who is it for?
- Adopt kneed if your data has a curve with a visible elbow, such as a scaling or cost curve that flattens out, and you want a reproducible point rather than a visual guess. Do not adopt it for noisy, non-monotone or ambiguous data, where the sensitivity parameter and the interpolation method start deciding the answer for you.
- 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 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem: a curve that stops paying for itself
Kneed is a Python library for detecting knee, or elbow, points in curves using the Kneedle algorithm. Given a set of x and y values, it returns the point of maximum curvature.
The problem it addresses is common in performance and capacity work. A curve that starts steep and then flattens has a point where additional effort buys progressively less, and the right answer to questions such as how many workers to provision or how large a cache to make is the bend in that curve rather than the last point on the axis. The origin of the method explains the framing: the algorithm comes from a 2011 paper, Finding a Kneedle in a Haystack, by Satopa, Albrecht, Irwin and Raghavan, presented at the 31st International Conference on Distributed Computing Systems Workshops.
The audience is therefore people working with system behaviour data rather than people looking for a general curve-fitting tool. The library does one thing, does it in a few lines, and leaves the interpretation to you, which is a reasonable division of labour for a heuristic that is well documented but not statistically rigorous.
It is a small package. The declared dependencies are numpy at 1.14.2 or newer and scipy at 1.0.0 or newer, the metadata classifies it as Production/Stable, and the licence is BSD-3-Clause.
What the algorithm actually computes
The mechanism is the Kneedle algorithm as described in the paper, and the library's parameters map onto the choices the algorithm has to make.
The curve shape is one choice: concave or convex. The direction is the other: increasing or decreasing functions are both supported. The sensitivity parameter S is the knob that decides how different the points on either side of the candidate have to be before the algorithm treats the difference as a real bend rather than noise, and it is listed in the features as a tunable sensitivity parameter.
Interpolation matters too. The library supports two interpolation methods, interp1d and polynomial, and the choice changes how the curve between your sampled points is modelled, which in turn changes where the maximum curvature is judged to be. For sparse or unevenly sampled data this is not a detail, because the shape you interpolate to is the shape the algorithm analyses.
The normalised plots make the mechanism visible. The library offers a plot of the normalised data, the normalised knee and the normalised distance curve, alongside a plot of the raw data and the knee. The distance curve is what the algorithm maximises, so seeing it next to your data is the fastest way to judge whether the detected knee is meaningful or an artefact of where your samples happen to fall.
Declaring the shape, or letting the library guess it
Using the library takes a curve, a shape and a direction. The straightforward version looks like this:
from kneed import KneeLocator, DataGenerator
# Generate sample data
x, y = DataGenerator.figure2()
# Find the knee point
kl = KneeLocator(x, y, curve="concave", direction="increasing")
print(kl.knee) # 0.222
print(kl.knee_y) # 1.897The DataGenerator class is a utility that produces sample datasets, and figure2 reproduces the curve from the original manuscript, which is what makes the printed values in the documentation checkable.
When you are not sure which shape or direction you have, the library can work it out for you:
from kneed import find_shape
direction, curve = find_shape(x, y)
kl = KneeLocator(x, y, curve=curve, direction=direction)Note the order of the returned values, direction first and curve second, which is the opposite of the order you pass them to the locator. That is a small thing that produces a confusing error when typed from memory.
One more detail about the result: the knee point returned is a value along the x axis. The y value at that point is a separate attribute, knee_y, and the elbow attribute is an alias for the same value, so knee and elbow are two names for one answer rather than two different points.
Installing kneed and its optional pieces
Installation is a standard Python package install, and there are three documented routes.
From conda-forge:
conda install -c conda-forge kneedFrom PyPI, where the plain install gives you the detection code only:
pip install kneed # knee-detection only
pip install kneed[plot] # also install matplotlib for visualizationsOr from a clone of the repository, which is the route for development:
git clone https://github.com/arvkevi/kneed.git && cd kneed
pip install -e .The extras matter more than usual here because the plotting functions are part of the library rather than a separate tool, and matplotlib is a heavier dependency than numpy or scipy. Installing the plain package and then calling plot_knee will fail on a missing import, so decide up front whether the visual check is part of your workflow.
The README states that kneed has been tested with Python 3.10, 3.11, 3.12, 3.13, 3.14 and 3.15, and the package metadata requires Python 3.10 or newer. The project builds with hatchling and takes its version from a file inside the package rather than hard-coding it in the project file, so the version reported by pip is the one recorded in the source tree.
Finding more than one knee
A single maximum-curvature point is the common case, but real system curves sometimes bend more than once. The online mode handles that, through the all_knees and all_elbows attributes, which return the collection of detected points rather than a single one.
The distinction between the two names mirrors the knee versus elbow naming elsewhere in the library: they refer to the same computation, and the difference is vocabulary that matches the conventions of the paper the algorithm comes from.
The practical reason to care is that a curve with several plateaus has several legitimate answers, and forcing one number out of it hides information. Working with the full list means you can see whether the detector finds a knee in every region you expected, which is also a cheap sanity check on your data before you trust the primary result.
The documentation site, kneed.readthedocs.io, is where the parameter tuning guides and the API reference live, and the README describes it as including real-world examples. The tuning guidance matters for this particular algorithm, since the sensitivity parameter is the control that decides how eagerly bends are reported.
Visualising the result and tuning it interactively
Two plotting functions are built into the class, one for the raw data with the knee marked and one for the normalised view:
# Normalized data, normalized knee, and normalized distance curve.
kneedle.plot_knee_normalized()# Raw data and knee.
kneedle.plot_knee()The README notes that all x and y values are transformed for the normalised plots, so a point read off the normalised chart is not the raw coordinate and the raw plot is the one to use when you want to quote a number.
For exploring how the parameters behave, the project points at an interactive Streamlit application, published at share.streamlit.io under the name ikneed, with its source in a separate repository. That is a useful complement to the static documentation because sensitivity and interpolation interact, and moving a slider shows the effect immediately in a way that a table of parameter values cannot.
The documentation itself is built with MkDocs, since the project metadata lists mkdocs-material, mkdocstrings and mkdocs-jupyter among its documentation extras, and the repository holds a notebooks directory, so the examples are executable rather than only transcribed.
Where kneed is the wrong tool
The first limitation is that a knee has to exist. The algorithm finds the point of maximum curvature on a curve with a particular shape and direction, and on a curve that is monotone, linear, noisy or multi-modal in a way that has no single dominant bend, the answer is a number without meaning. The library will still return one.
The second is that the result depends on choices you make rather than on the data alone. The sensitivity parameter S decides what counts as a bend, and the two interpolation methods model the space between your samples differently. Change either and the knee moves. For a decision you intend to defend, that means the sensitivity value and the interpolation method are part of your argument and should be recorded alongside the result.
The third is scope. Kneed is a heuristic from a workshop paper, and the library describes itself as returning the point of maximum curvature. It does not report uncertainty, it does not test whether a knee is statistically distinguishable from noise, and it does not validate that a piecewise model fits the data better than a straight line. If your decision needs any of those, you are past the end of what this library can tell you.
The practical alternative for many cases is to fit the models yourself. With scipy and numpy already available, comparing a segmented fit against a single curve and selecting on a criterion such as residual reduction is a handful of lines, and it gives you a defensible number. Kneed is faster to use and easier to explain, which is why it remains the default choice for a curve with an obvious elbow.
Packaging, testing and the citation requirement
The project is packaged with hatchling and keeps its tests in a dedicated directory, with pytest configuration in pytest.ini and coverage measured through pytest-cov. The packaging configuration defines two test environments in hatch, one with matplotlib and one without, and the environment without matplotlib runs a separate test file. That split is not decoration: it guarantees the library still imports and detects knees on a machine where the plotting extra was never installed, which is the configuration most production users end up with.
The repository also carries a CITATION.cff file, a readthedocs.yaml configuration and a docs directory, so the documentation site and the citation metadata are generated from the same source tree as the code.
The README asks that if you use kneed in your research you cite the paper by Satopa, Albrecht, Irwin and Raghavan, published in the 31st International Conference on Distributed Computing Systems Workshops, pages 166 to 171, with a BibTeX entry provided. The licence is BSD-3-Clause, with the licence file shipped alongside the package, and it is a permissive licence with no copyleft obligations on code that uses it.
The most recent release is v0.9.0, published on 2026-10-19, with v0.8.6 from 2026-03-20 before it and v0.8.5 from 2023-07-09 before that. The repository is not archived and the last push was on 2026-10-19, so the project is being maintained, and the three-year gap between two of those releases suggests bursts of work rather than a steady trickle.
Editorial conclusion
Adopt kneed if your data has a curve with a visible elbow, such as a scaling or cost curve that flattens out, and you want a reproducible point rather than a visual guess. Do not adopt it for noisy, non-monotone or ambiguous data, where the sensitivity parameter and the interpolation method start deciding the answer for you. Verify first that your curve has a direction and shape that the library supports, that the sensitivity value you choose leaves the knee in the region you expect, that find_shape agrees with your own reading of the curve, and that the package version you pin matches the Python version you run.
Frequently asked questions
How do I install kneed in Python?
Use pip install kneed for detection only, pip install kneed[plot] to pull in matplotlib for the plotting functions, or conda install -c conda-forge kneed. A clone of the repository can be installed in editable mode with pip install -e ., and the package requires Python 3.10 or newer.
How do I find more than one knee point in a curve?
Use the online mode, whose all_knees and all_elbows attributes return every detected point rather than the single knee attribute, which holds only the point of maximum curvature.
How do I know whether my curve is concave or convex?
The find_shape function inspects the data and returns the direction and the curve, which you can then pass straight to KneeLocator. The returned order is direction first and curve second.
How should kneed be cited in research?
Cite Satopa, Albrecht, Irwin and Raghavan, Finding a Kneedle in a Haystack, from the 31st International Conference on Distributed Computing Systems Workshops, pages 166 to 171. The repository also ships a CITATION.cff file.
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/arvkevi-kneed)Was this useful?