Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exponential memory leaks in two latest versions #2836

Closed
raykov opened this issue Jan 2, 2023 · 2 comments
Closed

Exponential memory leaks in two latest versions #2836

raykov opened this issue Jan 2, 2023 · 2 comments

Comments

@raykov
Copy link

raykov commented Jan 2, 2023

Brief summary

I noticed that with two latests versions of k6 0.41.0 & 0.42.0 it started to consume a lot of memory for no reason.

Deep investigation pointed out that this happens with http calls when url is random on each call. E.g.

http.get(`http://test.k6.io?a=${randomString(10)}&c=${randomString(10)}`);

This will cause process to consume over 2GiB in 10 minutes with only 100 VUs

k6 version

0.41.0 & 0.42.0

OS

macOS

Docker version and image (if applicable)

Docker 4.3.2, Images grafana/k6:0.41.0 & grafana/k6:0.42.0

Steps to reproduce the problem

0.41.0

First experiment: http://test.k6.io

script.js

import { sleep, randomSeed } from "k6";
import http from "k6/http";
import { randomString } from 'https://jslib.k6.io/k6-utils/1.4.0/index.js';

export function setup() {
    randomSeed(new Date().getTime());
}

export default function() {
    http.get(`http://test.k6.io`);

    sleep(0.5)
}
docker run  -e K6_STAGES="1m:100,10m:100" -v current_dir_with_script:/app   -i grafana/k6:0.41.0   run /app/test.js

Second experiment: http://test.k6.io?a=b&c=d

script.js

import { sleep, randomSeed } from "k6";
import http from "k6/http";
import { randomString } from 'https://jslib.k6.io/k6-utils/1.4.0/index.js';

export function setup() {
    randomSeed(new Date().getTime());
}

export default function() {
    http.get(`http://test.k6.io?a=b&c=d`);

    sleep(0.5)
}
docker run  -e K6_STAGES="1m:100,10m:100" -v current_dir_with_script:/app   -i grafana/k6:0.41.0   run /app/test.js

Third experiment: http://test.k6.io?a=${randomString(10)}&c=${randomString(10)}

script.js

import { sleep, randomSeed } from "k6";
import http from "k6/http";
import { randomString } from 'https://jslib.k6.io/k6-utils/1.4.0/index.js';

export function setup() {
    randomSeed(new Date().getTime());
}

export default function() {
    http.get(`http://test.k6.io?a=${randomString(10)}&c=${randomString(10)}`);

    sleep(0.5)
}
docker run  -e K6_STAGES="1m:100,10m:100" -v current_dir_with_script:/app   -i grafana/k6:0.41.0   run /app/test.js

Memory consumption over 3 tests, MiB
chart
Screenshot 2023-01-02 at 22 13 55

0.40.0 (previous version where this works fine)

First experiment: http://test.k6.io

script.js

import { sleep, randomSeed } from "k6";
import http from "k6/http";
import { randomString } from 'https://jslib.k6.io/k6-utils/1.4.0/index.js';

export function setup() {
    randomSeed(new Date().getTime());
}

export default function() {
    http.get(`http://test.k6.io`);

    sleep(0.5)
}
docker run  -e K6_STAGES="1m:100,10m:100" -v current_dir_with_script:/app   -i grafana/k6:0.40.0   run /app/test.js

Second experiment: http://test.k6.io?a=b&c=d

script.js

import { sleep, randomSeed } from "k6";
import http from "k6/http";
import { randomString } from 'https://jslib.k6.io/k6-utils/1.4.0/index.js';

export function setup() {
    randomSeed(new Date().getTime());
}

export default function() {
    http.get(`http://test.k6.io?a=b&c=d`);

    sleep(0.5)
}
docker run  -e K6_STAGES="1m:100,10m:100" -v current_dir_with_script:/app   -i grafana/k6:0.40.0   run /app/test.js

Third experiment: http://test.k6.io?a=${randomString(10)}&c=${randomString(10)}

script.js

import { sleep, randomSeed } from "k6";
import http from "k6/http";
import { randomString } from 'https://jslib.k6.io/k6-utils/1.4.0/index.js';

export function setup() {
    randomSeed(new Date().getTime());
}

export default function() {
    http.get(`http://test.k6.io?a=${randomString(10)}&c=${randomString(10)}`);

    sleep(0.5)
}
docker run  -e K6_STAGES="1m:100,10m:100" -v current_dir_with_script:/app   -i grafana/k6:0.40.0   run /app/test.js

Memory consumption over 3 tests, MiB
chart (1)
Screenshot 2023-01-02 at 22 39 21

Conclusions

As you can see, there is no such a drastically jump in memory consumption with version 0.40.0 with random url's in get requests

ps. I also tested with v 0.42.0, situation is the same.

Expected behaviour

stable memory consumption around 150 MiB over the test

Screenshot 2023-01-02 at 22 23 15

Actual behaviour

memory consumption growth exponentially over 2 GiB

Screenshot 2023-01-02 at 22 24 04

@na--
Copy link
Member

na-- commented Jan 3, 2023

Thank you for the super-detailed issue. Unfortunately, this is a known and unavoidable side-effect of our switch to support metric time-series in k6 v0.41.0 - every unique URL will now create a new time series, and thus use up a ton of RAM... 😞 Previously, this used to be a problem only for certain outputs, since k6 itself didn't keep track of different time series, but we now need to do it for a whole bunch of reasons.

Fortunately, there is an easy workaround - use URL grouping. In your case, unless you want to set the name tag manually, the only thing that you need to change is to use the http.url helper for the template literal, like this:

http.get(http.url`http://test.k6.io?a=${randomString(10)}&c=${randomString(10)}`);

For more details, you can read up the previous discussion on the topic in #2762. I'll close this issue, since grafana/k6-docs#883, #2765 and #2766 track the actionable parts of it that we plan to fix.

@na-- na-- closed this as completed Jan 3, 2023
@raykov
Copy link
Author

raykov commented Jan 3, 2023

Thank you @na-- for the prompt response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants