Skip to main content

Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Making efficient queries

Below are a few tips for getting data from the USGS Water Data APIs faster and with fewer repeated requests.

Limit the data you download

The slowest part of every API query is the time it takes to send data over the Internet from our servers to your computer. If you want your queries to run faster, the best thing you can do is to download less data.

One way to do this is to use the properties parameter to only download the data and metadata you're interested in. If provided, these APIs will only return the fields listed in properties with each request, which can significantly reduce the overall size of the response object.

For instance, if we're downloading the mean (statistic_id of 00003) daily value for stream discharge (parameter_code of 00065), we know that the statistic_id, parameter_code, and unit_of_measure fields in our response will always have the same values. As such, we can use the properties key to drop these fields from our download, shrinking the size of the response object and speeding our query up:

https://api.waterdata.usgs.gov/ogcapi/v0/collections/daily/items?limit=2&api_key=DEMO_KEY&datetime=2024-12-01/2024-12-31&statistic_id=00003&parameter_code=00065&properties=timeseries_id,monitoring_location_id,value,approvals_status,last_modified,time,qualifier
{
    "type":"FeatureCollection",
    "features":[
        {
            "type":"Feature",
            "properties":{
                "timeseries_id":"17d91ed719544fa38c8c6a1949a690b3",
                "monitoring_location_id":"USGS-05060000",
                "value":"8.07",
                "approvals_status":[
                    "Working"
                ],
                "last_modified":"2024-12-05T06:58:52.681608+00:00",
                "time":"2024-12-03",
                "qualifier":[
                    "SEASONAL"
                ]
            },
            "id":"03cc27ba-b76e-4d50-9253-b584f8d9146e",
            "geometry":{
                "type":"Point",
                "coordinates":[
                    -97.1064770662731,
                    46.8660826341224
                ]
            }
        },
        {
            "type":"Feature",
            "properties":{
                "timeseries_id":"00f2843003ed4b2aba79c811588c1663",
                "monitoring_location_id":"USGS-07161450",
                "value":"8.01",
                "approvals_status":[
                    "Working"
                ],
                "last_modified":"2024-12-05T02:20:39.407136+00:00",
                "time":"2024-12-02",
                "qualifier":null
            },
            "id":"0be65b91-47db-43e0-8b2e-bdff2b408a91",
            "geometry":{
                "type":"Point",
                "coordinates":[
                    -96.9122504261661,
                    35.9858926974527
                ]
            }
        }
    ],
    "numberMatched":62,
    "numberReturned":2,
    "links":[
        {
            "type":"application/geo+json",
            "rel":"self",
            "title":"This document as GeoJSON",
            "href":"https://api.waterdata.usgs.gov/ogcapi/v0/collections/daily/items?f=json&limit=2&datetime=2024-12-01%2F2024-12-31&statistic_id=00003&parameter_code=00065&properties=timeseries_id,monitoring_location_id,value,approvals_status,last_modified,time,qualifier"
        },
        {
            "rel":"alternate",
            "type":"application/ld+json",
            "title":"This document as RDF (JSON-LD)",
            "href":"https://api.waterdata.usgs.gov/ogcapi/v0/collections/daily/items?f=jsonld&limit=2&datetime=2024-12-01%2F2024-12-31&statistic_id=00003&parameter_code=00065&properties=timeseries_id,monitoring_location_id,value,approvals_status,last_modified,time,qualifier"
        },
        {
            "type":"text/html",
            "rel":"alternate",
            "title":"This document as HTML",
            "href":"https://api.waterdata.usgs.gov/ogcapi/v0/collections/daily/items?f=html&limit=2&datetime=2024-12-01%2F2024-12-31&statistic_id=00003&parameter_code=00065&properties=timeseries_id,monitoring_location_id,value,approvals_status,last_modified,time,qualifier"
        },
        {
            "type":"application/geo+json",
            "rel":"next",
            "title":"Items (next)",
            "href":"https://api.waterdata.usgs.gov/ogcapi/v0/collections/daily/items?offset=2&limit=2&datetime=2024-12-01%2F2024-12-31&statistic_id=00003&parameter_code=00065&properties=timeseries_id,monitoring_location_id,value,approvals_status,last_modified,time,qualifier"
        },
        {
            "type":"application/json",
            "title":"Daily values",
            "rel":"collection",
            "href":"https://api.waterdata.usgs.gov/ogcapi/v0/collections/daily"
        }
    ],
    "timeStamp":"2025-01-27T19:11:48.738301Z"
}

Depending on our application we might go even further. For instance, if we're not planning on incorporating timeseries or site level metadata, we might drop the ID fields from our list of properties, or drop the last_modified column. Each of these changes will shrink our total download size and speed our queries up.

Other ways to reduce the amount of time you spend downloading data is to reduce the amount of duplicate or overlapping downloads your application generates. For instance, if you're interested in only the most recent data (or the most recent updates), consider using the datetime or last_modified fields to only retrieve the most recent records that match the rest of your parameters.

Aim for a page of data per query

When you query these APIs, our server has to first go find all the records that match your query, and then split them up into pages to send back to your computer. This means that requests which match many records will take longer to execute -- and will be relatively slow to page through as the query gets re-run when generating each page.

As a result, the most efficient requests are ones that return about a page of data at a time. Knowing that these APIs can return up to 50,000 records per page, you can often chunk up requests into page-sized pieces. For instance, a time series that collects data every 15 minutes generates about 35,000 requests per year. As such, rather than making a request for 30 years of data and walking through the pages of the results, consider making 30 distinct requests for each year independently. You can additionally make these requests in parallel, further speeding up your download times.