Read-Replica Support for REST API RequestsSummary<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } Read replicas are read only copies of an instances primary database which reside in the same physical data centre as the primary database. Some queries can be offloaded from the primary database to read replicas to reduce load on the primary database. Read replicas are kept synchronized with the primary database via binlog replication and are generally added to a customers instance: At the sole discretion of ServiceNowWhen the primary database cannot be further scaled 'up' in size (Which means, it is already at the largest database size point)When there is evidence that primary database performance has become a bottleneck for overall instance performance When read replicas are configured, the ServiceNow platform will automatically offload some database queries from the primary to read replicas however queries run via the REST API will continue to be routed to the primary database and will not, by default, use read replicas. Offloading REST API queries from the primary database to read replicas is supported by the: Table APIAttachment APIAggregate API To allow the integrations queries to be routed to read replicas the REST request must include either of the following two parameters: sysparm_read_replica_categorysysparm_query_category Note that these two parameters: Are synonymous (Which means they both achieve the same functionality). Only one of these parameters needs to be included in the REST requestShould be set to a valid 'secondary database category' name (for example 'sysparm_query_category=odbc') - details of secondary categories within an instance can be seen by navigating to 'All' >> type 'sys_db_category.list' >> press enter. Selection of a particular category depends on the replica lag threshold required by the specific REST request. Example Consider the following REST URI: https://<instancename>.service-now.com/api/now/table/task?sysparm_query=active%3Dfalse%5EORassigned_to%[REDACTED_SYS_ID]%5EORsys_created_on%3Cjavascript%3Ags.beginningOfLastWeek()&sysparm_limit=10 This request: Is using the REST table API (so its queries are eligible for offloading to read replicas)Does not contain either the sysparm_read_replica_category or sysparm_query_category As a result queries from this request will be routed to the primary database. This can be identified from application node localhost logs as, when the request is executed, corresponding queries are seen to use a database connection of 'glide.[connection]': 2018-05-09 01:46:19 (574) API_INT-thread-4 503D09DC134E13004475B5F12244B0A2 txid=d03d49dc134e #1603 [REST API] RESTAPIProcessor : EXTERNAL_USER_REST_ACCESS: user='abcdxyz' api='/api/now/table/task'...2018-05-09 01:46:20 (002) API_INT-thread-4 503D09DC134E13004475B5F12244B0A2 txid=d03d49dc134e Time: 0:00:00.425 id: instancename_1[glide.11] for: SELECT count(*) AS recordcount FROM task task0 WHERE (task0.`active` = 0 OR task0.`assigned_to` = '[REDACTED_SYS_ID]' OR task0.`sys_created_on` < '2018-04-30 07:00:00') AND (task0.`sys_domain_path` = '/' OR task0.`sys_domain_path` LIKE '!!!/!!#/!!!/%') /* instancename005, gs:503D09DC134E13004475B5F12244B0A2, tx:d03d49dc134e13004475b5f12244b02b */ To allow queries from the request to be routed to read replicas using a pre-defined secondary database category of 'jfcategory' the URI can be modified as follows (note that the sysparm_query_category parameter has been added to the URI): https://<instancename>.service-now.com/api/now/table/task?sysparm_query=active%3Dfalse%5EORassigned_to%3D[REDACTED_SYS_ID]%5EORsys_created_on%3Cjavascript%3Ags.beginningOfLastWeek()&sysparm_limit=10&sysparm_query_category=jfcategory If the request is executed using the modified URI, queries are clearly seen to be routed to read replicas as expected - this is indicated by use of the 'read-replica-1-IAD1.[connection]' database connection (note that the connection name may be different between instances - as long as it is not using 'glide.[x]' then the query is being routed to read replicas): 2018-05-09 01:55:50 (803) API_INT-thread-3 F35F4150138E13004475B5F12244B09D txid=f35f8d10138e #1623 [REST API] RESTAPIProcessor : EXTERNAL_USER_REST_ACCESS: user='instanceabcd' api='/api/now/table/task'...2018-05-09 01:55:52 (269) API_INT-thread-3 F35F4150138E13004475B5F12244B09D txid=f35f8d10138e Time: 0:00:01.451 id: instancename_1[read-replica-1-IAD1.6] for: SELECT count(*) AS recordcount FROM task task0 WHERE (task0.`active` = 0 OR task0.`assigned_to` = '[REDACTED_SYS_ID]' OR task0.`sys_created_on` < '2018-04-30 07:00:00') AND (task0.`sys_domain_path` = '/' OR task0.`sys_domain_path` LIKE '!!!/!!#/!!!/%') Note that: Read replica databases are read only. As such, all 'write'/'PUT' requests will always be routed to the primary database.Queries will only be routed to read replica systems if read replica lag is below the threshold set for the secondary database category provided - if this is not the case, queries will be routed to the primary database. As mentioned previously, the sys_query_category and sys_read_replica_category parameters are synonymous, so only one parameter should be added to the REST request URI. If both are provided with different values, the REST request will fail as shown below: 2018-05-24 07:17:13 (653) API_INT-thread-4 71C8AF85131ADB00D4C050F32244B0AE txid=46c8ef85131a #36320 /api/now/table/task Parameters ------------------------- sysparm_query=active=false^ORassigned_to=[REDACTED_SYS_ID]^ORsys_created_on<javascript:gs.beginningOfLastWeek() api=api sysparm_limit=10 sysparm_read_replica_category=jfcategory <=== NOTE sysparm_query_category=odbc <=== NOTE 2018-05-24 07:17:13 (653) API_INT-thread-4 71C8AF85131ADB00D4C050F32244B0AE txid=46c8ef85131a #36320 [REST API] RESTAPIProcessor : EXTERNAL_USER_REST_ACCESS: user='instancename' api='/api/now/table/task' 2018-05-24 07:17:13 (655) API_INT-thread-4 71C8AF85131ADB00D4C050F32244B0AE txid=46c8ef85131a #36320 [REST API] RESTAPIProcessor : Ambiguous query category value 2018-05-24 07:17:13 (656) API_INT-thread-4 71C8AF85131ADB00D4C050F32244B0AE txid=46c8ef85131a *** End #36320 /api/now/table/task, user: instanceuser, total time: 0:00:00.021, processing time: 0:00:00.021, SQL time: 0:00:00.007 (count: 16) , type:rest, method:GET, api_name:now/table, resource:now/table/task, version:Default, user_id:[REDACTED_SYS_ID], response_status:400