@@ -11,10 +11,9 @@ For guideline purposes we perform load test on **Permify** with 1000 VU and 1000
1111
1212## 1. Test Environment
1313
14- - Permify version ** 1.3.0 **
14+ - Permify version ** 1.6.9 **
1515- Google Kubernetes Engine general-purpose machines for clusters
1616- Postgres 15 on Google Cloud SQL
17- - pgcat for server side pooling
1817- ** [ values.yaml] ( ./values.yaml ) ** : This file holds the default configuration (e.g. Helm values, resource settings, etc.) used for the performance test environment.
1918
2019## 2. Schema
@@ -48,17 +47,115 @@ entity interaction {
4847```
4948
5049## 3. K6 Test Script
51- Below is the k6test.js script used to measure load on Permify by performing both write and check requests:
50+
51+ ### Write Script
52+ Seeds data for the schema used in our load tests.
53+ ``` javascript
54+ import http from " k6/http" ;
55+ import { fail } from " k6" ;
56+
57+ export const options = { vus: 1 , iterations: 1 };
58+
59+ const TENANT_ID = " <tenant-id>" ;
60+ const url = " <your-api-endpoint>" ;
61+
62+ const TOTAL_IDS = 100000 ;
63+ const BATCH_SIZE = 1000 ;
64+
65+ function writeInBatches (items , key ) {
66+ for (let start = 0 ; start < items .length ; start += BATCH_SIZE ) {
67+ const chunk = items .slice (start, start + BATCH_SIZE );
68+ const batchNumber = start / BATCH_SIZE + 1 ;
69+ const res = http .post (
70+ ` ${ url} /v1/tenants/${ TENANT_ID } /data/write` ,
71+ JSON .stringify ({
72+ metadata: { schema_version: " <schema-version>" },
73+ [key]: chunk,
74+ }),
75+ {
76+ headers: { " Content-Type" : " application/json" },
77+ }
78+ );
79+
80+ if (res .status < 200 || res .status >= 300 ) {
81+ console .error (` \n POST /data/write ${ key} batch ${ batchNumber} FAILED status=${ res .status } \n body=\n ${ res .body } \n ` );
82+ fail (` POST /data/write ${ key} batch ${ batchNumber} non-2xx` );
83+ }
84+ }
85+ }
86+
87+ export default function () {
88+ const tuples = [];
89+ const attributes = [];
90+
91+ for (let i = 0 ; i < TOTAL_IDS ; i++ ) {
92+ const id = String (i);
93+ const nextId = String ((i + 1 ) % TOTAL_IDS );
94+ const blockedId = String ((i + 2 ) % TOTAL_IDS );
95+ const isPublic = i % 4 === 0 ;
96+
97+ tuples .push (
98+ {
99+ entity: { type: " user" , id },
100+ relation: " self" ,
101+ subject: { type: " user" , id, relation: " " },
102+ },
103+ {
104+ entity: { type: " user" , id },
105+ relation: " follower" ,
106+ subject: { type: " user" , id: nextId, relation: " " },
107+ },
108+ {
109+ entity: { type: " user" , id },
110+ relation: " blocked" ,
111+ subject: { type: " user" , id: blockedId, relation: " " },
112+ },
113+ {
114+ entity: { type: " content" , id },
115+ relation: " owner" ,
116+ subject: { type: " user" , id, relation: " " },
117+ },
118+ {
119+ entity: { type: " interaction" , id },
120+ relation: " creator" ,
121+ subject: { type: " user" , id, relation: " " },
122+ },
123+ {
124+ entity: { type: " interaction" , id },
125+ relation: " parent" ,
126+ subject: { type: " content" , id, relation: " " },
127+ }
128+ );
129+
130+ attributes .push (
131+ {
132+ entity: { type: " user" , id },
133+ attribute: " is_public" ,
134+ value: { boolean: isPublic },
135+ },
136+ {
137+ entity: { type: " content" , id },
138+ attribute: " is_public" ,
139+ value: { boolean: isPublic },
140+ }
141+ );
142+ }
143+
144+ writeInBatches (tuples, " tuples" );
145+ writeInBatches (attributes, " attributes" );
146+
147+ console .log (` Seeded ${ TOTAL_IDS } users, ${ TOTAL_IDS } contents, and ${ TOTAL_IDS } interactions` );
148+ }
149+ ```
150+
151+ ### Test Script
152+
153+ Below is the k6test.js script used to measure load on Permify by performing check requests:
52154``` javascript
53155import http from ' k6/http' ;
54156import {check , sleep } from ' k6' ;
55157
56158export let options = {
57- cloud: {
58- distribution: {
59- distributionLabel1: {loadZone: ' amazon:de:frankfurt' , percent: 100 },
60- },
61- },
62159 scenarios: {
63160 contacts_load: {
64161 executor: ' ramping-arrival-rate' ,
@@ -79,26 +176,28 @@ function getRandomId() {
79176 return Math .floor (Math .random () * 100000 ).toString ();
80177}
81178
82- let reuseIdProbability = 0.3 ;
83- let currentId = getRandomId ();
179+ let reuseIdProbability = 0.1 ;
180+ let currentEntityId = getRandomId ();
181+ let currentSubjectId = getRandomId ();
84182
85183export default function () {
86184 let entityId, subjectId;
185+ const entityType = Math .random () < 0.5 ? ' content' : ' interaction' ;
87186
88187 // Decide whether to reuse the current ID for the entity
89188 if (Math .random () < reuseIdProbability) {
90- entityId = currentId ; // Reuse the existing ID
189+ entityId = currentEntityId ; // Reuse the existing entity ID
91190 } else {
92- entityId = getRandomId (); // Generate a new ID
93- currentId = entityId; // Update current ID to the new one
191+ entityId = getRandomId (); // Generate a new entity ID
192+ currentEntityId = entityId; // Update current entity ID
94193 }
95194
96195 // Decide whether to reuse the current ID for the subject
97196 if (Math .random () < reuseIdProbability) {
98- subjectId = currentId ; // Reuse the existing ID
197+ subjectId = currentSubjectId ; // Reuse the existing subject ID
99198 } else {
100- subjectId = getRandomId (); // Generate a new ID
101- currentId = subjectId; // Update current ID to the new one
199+ subjectId = getRandomId (); // Generate a new subject ID
200+ currentSubjectId = subjectId; // Update current subject ID
102201 }
103202
104203 const url = ' <your-api-endpoint>' ;
@@ -109,7 +208,7 @@ export default function () {
109208 depth: 20
110209 },
111210 entity: {
112- type: " content " ,
211+ type: entityType ,
113212 id: entityId,
114213 },
115214 permission: ' view' ,
@@ -160,21 +259,21 @@ export default function () {
160259
161260| ** Metric** | ** Value/Stats** |
162261| --------------------------------| -------------------------------------------------------------------------------|
163- | ** checks** | 100.00% (75369 out of 75369 ) |
164- | ** data_received** | 15 MB (145 kB/s) |
165- | ** data_sent** | 21 MB (203 kB/s) |
166- | ** dropped_iterations** | 271664 (2688.447952 /s) |
167- | ** http_req_blocked** | avg=78.61µs min=208ns med=537ns max=45.53ms p(90)=775ns p(95)=885ns |
168- | ** http_req_connecting** | avg=16.27µs min=0s med=0s max=15.27ms p(90)=0s p(95)=0s |
169- | ** http_req_duration** | avg=10.14ms min=1.61ms med=7.44ms max=295.29ms p(90)=14.3ms p(95)=26.34ms |
170- | ** expected_response** | avg=10.14ms min=1.61ms med=7.44ms max=295.29ms p(90)=14.3ms p(95)=26.34ms |
171- | ** http_req_failed** | 0.00% (0 out of 75369 ) |
172- | ** http_req_receiving** | avg=94.63µs min=15.55µs med=70.42µs max=37.13ms p(90)=168.34µs p(95)=234.35µs |
173- | ** http_req_sending** | avg=86.07µs min=25.5µs med=69.44µs max=10.25ms p(90)=121.44µs p(95)=171.32µs |
262+ | ** checks** | 100.00% (74614 out of 74614 ) |
263+ | ** data_received** | 17 MB (168 kB/s) |
264+ | ** data_sent** | 27 MB (268 kB/s) |
265+ | ** dropped_iterations** | 272433 (2696.482348 /s) |
266+ | ** http_req_blocked** | avg=5.59µs min=0s med=2µs max=2.08ms p(90)=4µs p(95)=5µs |
267+ | ** http_req_connecting** | avg=2.57µs min=0s med=0s max=2.04ms p(90)=0s p(95=0s |
268+ | ** http_req_duration** | avg=21.3ms min=428µs med=15.38ms max=617.85ms p(90)=45.7ms p(95)=58.99ms |
269+ | ** expected_response** | avg=21.3ms min=428µs med=15.38ms max=617.85ms p(90)=45.7ms p(95)=58.99ms |
270+ | ** http_req_failed** | 0.00% (0 out of 74614 ) |
271+ | ** http_req_receiving** | avg=20.27µs min=4µs med=17µs max=2.86ms p(90)=37µs p(95)=44µs |
272+ | ** http_req_sending** | avg=11.16µs min=1µs med=8µs max=2.51ms p(90)=18µs p(95)=22µs |
174273| ** http_req_tls_handshaking** | avg=59.38µs min=0s med=0s max=44.21ms p(90)=0s p(95)=0s |
175- | ** http_req_waiting** | avg=9.96ms min=1.41ms med=7.27ms max=295.21ms p(90)=14.1ms p(95)=26.17ms |
176- | ** http_reqs** | 75369 (745.86855 /s) |
177- | ** iteration_duration** | avg=1.01s min=1s med=1s max=1.29s p(90)=1.01s p(95)=1.02s |
178- | ** iterations** | 75369 (745.86855 /s) |
179- | ** vus** | 46 (min=13 , max=1000) |
274+ | ** http_req_waiting** | avg=21.27ms min=399µs med=15.35ms max=617.83ms p(90)=45.67ms p(95)=58.96ms |
275+ | ** http_reqs** | 74614 (738.51308 /s) |
276+ | ** iteration_duration** | avg=1.02s min=1s med=1.01s max=1.61s p(90)=1.04s p(95)=1.05s |
277+ | ** iterations** | 74614 (738.51308 /s) |
278+ | ** vus** | 114 (min=14 , max=1000) |
180279| ** vus_max** | 1000 (min=50, max=1000) |
0 commit comments