PageSourceSearch

https://docs-pactflow-preview.netlify.app/assets/js/a6a28c79.96e4dfa6.js

js docs-pactflow-preview.netlify.app collected 2026-10-03 10:42:16 UTC 12,303 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkpartners=self.webpackChunkpartners||[]).push([[26832],{15680:(e,a,t)=>{t.d(a,{xA:()=>c,yg:()=>g});var n=t(96540);function r(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function i(e,a){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);a&&(n=n.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),t.push.apply(t,n)}return t}function o(e){for(var a=1;a<arguments.length;a++){var t=null!=arguments[a]?arguments[a]:{};a%2?i(Object(t),!0).forEach((function(a){r(e,a,t[a])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(a){Object.defineProperty(e,a,Object.getOwnPropertyDescriptor(t,a))}))}return e}function s(e,a){if(null==e)return{};var t,n,r=function(e,a){if(null==e)return{};var t,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],a.indexOf(t)>=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],a.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=n.createContext({}),u=function(e){var a=n.useContext(l),t=a;return e&&(t="function"==typeof e?e(a):o(o({},a),e)),t},c=function(e){var a=u(e.components);return n.createElement(l.Provider,{value:a},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},d=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=u(t),d=r,g=p["".concat(l,".").concat(d)]||p[d]||m[d]||i;return t?n.createElement(g,o(o({ref:a},c),{},{components:t})):n.createElement(g,o({ref:a},c))}));function g(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var i=t.length,o=new Array(i);o[0]=d;var s={};for(var l in a)hasOwnProperty.call(a,l)&&(s[l]=a[l]);s.originalType=e,s[p]="string"==typeof e?e:r,o[1]=s;for(var u=2;u<i;u++)o[u]=t[u];return n.createElement.apply(null,o)}return n.createElement.apply(null,t)}d.displayName="MDXCreateElement"},57907:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var n=t(58168),r=(t(96540),t(15680));const i={title:"System requirements"},o=void 0,s={unversionedId:"docs/on-premises/system-requirements",id:"docs/on-premises/system-requirements",title:"System requirements",description:"Application server instance",source:"@site/docs/docs/on-premises/system-requirements.md",sourceDirName:"docs/on-premises",slug:"/docs/on-premises/system-requirements",permalink:"/docs/on-premises/system-requirements",draft:!1,editUrl:"https://github.com/pactflow/docs.pactflow.io/edit/master/website/docs/docs/on-premises/system-requirements.md",tags:[],version:"current",lastUpdatedBy:"Yousaf Nabi",lastUpdatedAt:1674493712,formattedLastUpdatedAt:"Jan 23, 2023",frontMatter:{title:"System requirements"},sidebar:"onprem",previous:{title:"Architecture",permalink:"/docs/on-premises"},next:{title:"Docker image registry",permalink:"/docs/on-premises/docker-image-registry"}},l={},u=[{value:"Application server instance",id:"application-server-instance",level:2},{value:"OS",id:"os",level:3},{value:"Minimum CPU/Memory",id:"minimum-cpumemory",level:3},{value:"Disk space usage",id:"disk-space-usage",level:3},{value:"Docker version",id:"docker-version",level:3},{value:"Postgres database instance",id:"postgres-database-instance",level:2},{value:"HA Configuration",id:"ha-configuration",level:3},{value:"Configuration",id:"configuration",level:3},{value:"Minimum CPU/Memory",id:"minimum-cpumemory-1",level:3},{value:"Storage",id:"storage",level:3},{value:"I/O Performance",id:"io-performance",level:3},{value:"Load Balancing",id:"load-balancing",level:2},{value:"Scaling and Monitoring",id:"scaling-and-monitoring",level:2},{value:"Benchmarking and Forecasting",id:"benchmarking-and-forecasting",level:2},{value:"Standard Units",id:"standard-units",level:3},{value:"Examples",id:"examples",level:3}],c={toc:u},p="wrapper";
1function m(e){let{components:a,...t}=e;return(0,r.yg)(p,(0,n.A)({},c,t,{components:a,mdxType:"MDXLayout"}),(0,r.yg)("h2",{id:"application-server-instance"},"Application server instance"),(0,r.yg)("h3",{id:"os"},"OS"),(0,r.yg)("p",null,"Linux"),(0,r.yg)("h3",{id:"minimum-cpumemory"},"Minimum CPU/Memory"),(0,r.yg)("p",null,"4.0 GiB Memory, 4 vCPUs"),(0,r.yg)("h3",{id:"disk-space-usage"},"Disk space usage"),(0,r.yg)("p",null,"4.0 GiB"),(0,r.yg)("h3",{id:"docker-version"},"Docker version"),(0,r.yg)("p",null,"20.10.0 or later"),(0,r.yg)("h2",{id:"postgres-database-instance"},"Postgres database instance"),(0,r.yg)("h3",{id:"ha-configuration"},"HA Configuration"),(0,r.yg)("h3",{id:"configuration"},"Configuration"),(0,r.yg)("p",null,"We would recommend running Postgres as an Active/Passive setup with ",(0,r.yg)("a",{parentName:"p",href:"https://wiki.postgresql.org/wiki/Replication,_Clustering,_and_Connection_Pooling"},"streaming replication"),", or Active/Active setup for the best availability."),(0,r.yg)("p",null,"For reference, pactflow.io runs on AWS RDS in ",(0,r.yg)("a",{parentName:"p",href:"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html"},"active/passive mode across multiple logical networks"),", and fails over to the replica when in a failure mode."),(0,r.yg)("h3",{id:"minimum-cpumemory-1"},"Minimum CPU/Memory"),(0,r.yg)("p",null,"4.0 GiB Memory, 4 vCPUs"),(0,r.yg)("h3",{id:"storage"},"Storage"),(0,r.yg)("p",null,"5GiB (minimum)\n25GiB (recommended)"),(0,r.yg)("h3",{id:"io-performance"},"I/O Performance"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"10 read/s"),(0,r.yg)("li",{parentName:"ul"},"25 write/s")),(0,r.yg)("h2",{id:"load-balancing"},"Load Balancing"),(0,r.yg)("p",null,"We recommend running PactFlow on load-balanced infrastructure in at least a 2 node setup to enable high availability and greater throughput. So for clarity, we would recommend running two servers both with 4GiB memory and 4 CPUs for a total capacity of 8GiB Memory and 8 CPUs."),(0,r.yg)("p",null,"The PactFlow application is stateless, and therefore sticky sessions do not need to be configured. Use round-robin or least outstanding requests to route to the application servers."),(0,r.yg)("p",null,(0,r.yg)("em",{parentName:"p"},"NOTE"),": Most Pact tooling has retries built-in to handle minor outages communicating to a broker."),(0,r.yg)("h2",{id:"scaling-and-monitoring"},"Scaling and Monitoring"),(0,r.yg)("p",null,"Below are the key scaling considerations."),(0,r.yg)("p",null,"First, make sure you've identified the baseline load and have performed a ",(0,r.yg)("a",{parentName:"p",href:"installation/load-testing"},"load test"),". This will help you to set you boundaries for your scale out and scale in parameters."),(0,r.yg)("p",null,"PactFlow is a database intensive application, with the I/O performance of the database being the most critical factor in determining overall system performance. You should setup monitoring for the following metrics:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"CPU"),(0,r.yg)("li",{parentName:"ul"},"Memory"),(0,r.yg)("li",{parentName:"ul"},"I/O latency"),(0,r.yg)("li",{parentName:"ul"},"Query latency"),(0,r.yg)("li",{parentName:"ul"},"Remaining storage space")),(0,r.yg)("p",null,"Application servers tend to be more CPU bound, but you should look to monitor and scale at least:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"CPU"),(0,r.yg)("li",{parentName:"ul"},"Memory")),(0,r.yg)("h2",{id:"benchmarking-and-forecasting"},"Benchmarking and Forecasting"),(0,r.yg)("p",null,"The usage patterns of every customer is different. For example, we have several customers who are among top users of our SaaS platform with less than 30 integrations."),(0,r.yg)("p",null,"Things that will affect how the system scales include:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Concurrent usage i.e. requests per second (usually by automation systems such as CI/CD)"),(0,r.yg)("li",{parentName:"ul"},"CI implementation patterns (e.g. integrations to PactFlow, the use of polling vs webhooks)"),(0,r.yg)("li",{parentName:"ul"},"Developer habits (continuous check-in vs bigger commits) causing more or less builds"),(0,r.yg)("li",{parentName:"ul"},"Whether you run regular database cleanups (to reduce database storage requirements, and speed up queries)"),(0,r.yg)("li",{parentName:"ul"},"The size, variation and stability of contracts"),(0,r.yg)("li",{parentName:"ul"},"The interconnectedness of your system"),(0,r.yg)("li",{parentName:"ul"},"Database growth")),(0,r.yg)("p",null,"and so on. These types of data are very hard to collect, measure and predict."),(0,r.yg)("p",null,"For forecasting purposes we've created a standard model you can use for projecting storage and compute costs as you grow, which is based on the number of active users",(0,r.yg)("sup",null,"*")," you have on the system."),(0,r.yg)("p",null,(0,r.yg)("em",{parentName:"p"},"NOTE"),": We still recommend using the monitoring and scaling approach (defined above) to automatically scale up/down your system as required."),(0,r.yg)("p",null,(0,r.yg)("em",{parentName:"p"},(0,r.yg)("sup",null,"*")," Active users is defined as a developer that either logs into PactFlow daily or commits code that would trigger a CI build that integrates with Pactflow")),(0,r.yg)("h3",{id:"standard-units"},"Standard Units"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"1 ",(0,r.yg)("inlineCode",{parentName:"li"},"compute unit"),"  = 1 CPU, 256 MiB memory"),(0,r.yg)("li",{parentName:"ul"},"1 ",(0,r.yg)("inlineCode",{parentName:"li"},"database unit")," = 1 CPU, 256 MiB memory, 1 GiB storage (per week), 25 writes/s, 10 read/s")),(0,r.yg)("p",null,"For each 500 active users",(0,r.yg)("sup",null,"*"),", you should increment your total compute capacity by one (1) unit, and ",(0,r.yg)("em",{parentName:"p"},"each")," database server capacity by one (1) unit."),(0,r.yg)("h3",{id:"examples"},"Examples"),(0,r.yg)("p",null,(0,r.yg)("em",{parentName:"p"},(0,r.yg)("strong",{parentName:"em"},"Scenario 1"),": 1000 users in year 1")),(0,r.yg)("p",null,"Assuming our database uses active/passive mode and replication."),(0,r.yg)("p",null,"Baseline capacity should be 2 x Application Servers each with 4 CPU and 4GiB memory, and a two Postgres database instances (one for the active and passive) each with 4CPU, 4GiB memory, 25Gi
1B volume and 25/10 write/read per second."),(0,r.yg)("p",null,"To calculate the number of standard units you need to add:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"new units = expected users / 500\n          = 1000 / 500\n          = 2 units\n")),(0,r.yg)("p",null,"You should therefore add 2 CPUs and 512 MiB to your total compute budget, and add 2 CPUs, 512 MiB of memory and 104 GiB storage capacity to each of your database instances in year 1, for a total budget:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Compute"),": 10 CPU, 8.5 GiB RAM (measured by total resources and not physical instances)"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Database"),": 2 x database servers each with 6 CPU, 4.5 GiB RAM, 75 writes/s, 30 read/s, 129 GiB storage")),(0,r.yg)("p",null,(0,r.yg)("em",{parentName:"p"},(0,r.yg)("strong",{parentName:"em"},"Scenario 2"),": Additional 1300 users in year 2")),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"new units = expected users / 500\n          = 1300 / 500\n          = 3 units (rounded)\n")),(0,r.yg)("p",null,"You should therefore add 3 CPUs and 768 MiB to your total compute budget, and add 3 CPUs, 768 MiB of memory and 156 GiB storage capacity to each of your database instances in year 2, for a total budget:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Compute"),": 13 CPU, 9.25 GiB RAM (measured by total resources and not physical instances)"),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Database"),": 2 x database servers each with 9 CPU, 5.25 GiB RAM, 150 writes/s, 60 read/s, 285 GiB storage")))}m.isMDXComponent=!0}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.