# How to Bulk update Synthesis ICMP monitor frequency?

**URL:** <https://discuss.elastic.co/t/how-to-bulk-update-synthesis-icmp-monitor-frequency/385291>\
**Category:** Synthetics\
**Created:** [March 2, 2026, 3:42am UTC](https://discuss.elastic.co/t/how-to-bulk-update-synthesis-icmp-monitor-frequency/385291 "2026-03-02T03:42:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Whoami1980](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whoami1980/32/147545_2.png) [@Whoami1980](https://discuss.elastic.co/u/Whoami1980)\
**Post date:** [March 2, 2026, 3:42am UTC](https://discuss.elastic.co/t/how-to-bulk-update-synthesis-icmp-monitor-frequency/385291/1 "2026-03-02T03:42:58Z")

</div>

Our ELK is 8.19 We are using Synthetics monitoring. We have about 5000 ICMP monitors.

The current ICMP Ping frequency is currently 3 minutes.

Our customer have a request to update all to 1 minute.

What’s our best option to do it? If via API can only share an example of the script.

How can I run a query or report to check which monitor is not updated to 1 minute

Also in terms of load. How can we monitor that this is not having an impact?

KIndly advice

---

<div class="post-metadata">

**Author:** ![carly.richmond](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/carly.richmond/32/104935_2.png) [@carly.richmond](https://discuss.elastic.co/u/carly.richmond)\
**Post date:** [March 2, 2026, 10:21am UTC](https://discuss.elastic.co/t/how-to-bulk-update-synthesis-icmp-monitor-frequency/385291/2 "2026-03-02T10:21:33Z")

</div>

Hi @Whoami1980,

For 5000 monitors I would recommend scripting the updates via the below APIs:

1. You can get a hold of all ICMP monitors using the [Get monitors API](https://www.elastic.co/docs/api/doc/kibana/operation/operation-get-synthetic-monitors) filtering using the `monitorType` attribute to filter for `icmp` monitors.
2. Then you can loop through each one, using the `id` in a subsequent call to the [Update monitors API](https://www.elastic.co/docs/api/doc/kibana/operation/operation-put-synthetic-monitor), specifying the `schedule` value as `1`.
3. You should be able to track the HTTP response calls for failure. Alternatively the [Get monitors API](https://www.elastic.co/docs/api/doc/kibana/operation/operation-get-synthetic-monitors) can be invoked again using the `monitorType` and `schedules` filters.

I'm not sure of the load impact of running for 5000 monitors on your cluster. I would recommend you consider batching the update requests. You can also leverage [AutoOps and Stack Monitoring](https://www.elastic.co/docs/deploy-manage/monitor) to track the load.

Hope that helps!

---

<div class="post-metadata">

**Author:** ![Whoami1980](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whoami1980/32/147545_2.png) [@Whoami1980](https://discuss.elastic.co/u/Whoami1980)\
**Post date:** [March 3, 2026, 1:13am UTC](https://discuss.elastic.co/t/how-to-bulk-update-synthesis-icmp-monitor-frequency/385291/3 "2026-03-03T01:13:30Z")

</div>

@carly.richmond

Can I clarify if this is what you want me to do?

Kibana REST APIs  
GET kbn:/api/synthetics/monitors?filter=synthetics-monitor.attributes.type:icmp

Is it better or easier for me to do this instead?

Query DSL

```auto
### GET QUERY ###

GET synthetics-*/_search
{
  "_source": ["monitor.name", "config_id", "schedule", "monitor.type"],
  "track_total_hits": true,
  "size": 50,
  "query": {
    "bool": {
      "must": [
        { "term": { "monitor.type": "icmp" } },
        { "term": { "schedule.number": 3 } },
        { "term": { "schedule.unit": "m" } }
      ]
    }
  },
  "collapse": {
    "field": "monitor.name.keyword",
    "inner_hits": {
      "name": "latest_check",
      "size": 1,
      "sort": [{ "@timestamp": "desc" }]
    }
  },
  "sort": [
    { "@timestamp": "desc" }
  ]
}

### UPDATE QUERY ###

POST synthetics-*/_update_by_query
{
  "script": {
    "source": """
      if (ctx._source.monitor.type == 'icmp' &&
          ctx._source.schedule.number == 3 &&
          ctx._source.schedule.unit == 'm') {
        ctx._source.schedule.number = 1;
      }
    """,
    "lang": "painless"
  },
  "query": {
    "bool": {
      "must": [
        { "term": { "monitor.type": "icmp" } },
        { "term": { "schedule.number": 3 } },
        { "term": { "schedule.unit": "m" } }
      ]
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![Tortoise](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tortoise/32/147587_2.png) [@Tortoise](https://discuss.elastic.co/u/Tortoise)\
**Post date:** [March 3, 2026, 5:07am UTC](https://discuss.elastic.co/t/how-to-bulk-update-synthesis-icmp-monitor-frequency/385291/4 "2026-03-03T05:07:48Z")

</div>

Hello @Whoami1980

I tried above queries but it did not work via Dev Tools..Used below 2 shell scripts to update the records & it worked :

**fetch-synthetics-icmp.sh**

```auto
#!/bin/bash

KIBANA_URL="Kibana_URL"
API_KEY="API_Key"
PER_PAGE=1000
PAGE=1

while : ; do
  RESPONSE=$(curl -s -X GET \
    "$KIBANA_URL/api/synthetics/monitors?monitorTypes=icmp&page=$PAGE&perPage=$PER_PAGE" \
    -H "kbn-xsrf: true" \
    -H "Authorization: ApiKey $API_KEY")

  COUNT=$(echo "$RESPONSE" | jq '.monitors | length')

  if ["$COUNT" -eq 0]; then
    break
  fi

  echo "$RESPONSE" | jq -r '.monitors[]
  | select(.schedule.number=="3" and .schedule.unit=="m")
  | "\(.id) | \(.name) | \(.schedule.number)\(.schedule.unit) | space=\(.spaceId)"'

  PAGE=$((PAGE + 1))
done

```

**update-synthetics-icmp.sh**

```auto
#!/bin/bash

KIBANA_URL="Kibana_URL"
API_KEY="API_Key"

SPACE="default" # change if using another space
PER_PAGE=1000
PAGE=1

echo "Updating ICMP monitors from 3m to 1m..."
echo "-----------------------------------------"

while true; do

  RESPONSE=$(curl -s -X GET \
    "$KIBANA_URL/s/$SPACE/api/synthetics/monitors?monitorTypes=icmp&page=$PAGE&perPage=$PER_PAGE" \
    -H "kbn-xsrf: true" \
    -H "Authorization: ApiKey $API_KEY")

  COUNT=$(echo "$RESPONSE" | jq '.monitors | length')

  if ["$COUNT" -eq 0] || ["$COUNT" = "null"]; then
    break
  fi

  for ROW in $(echo "$RESPONSE" | jq -r '.monitors[] | @base64'); do

    _jq() {
      echo "$ROW" | base64 --decode | jq -r "$1"
    }

    NUMBER=$(_jq '.schedule.number')
    UNIT=$(_jq '.schedule.unit')

    if [["$NUMBER" == "3" && "$UNIT" == "m"]]; then

      ID=$(_jq '.id')
      NAME=$(_jq '.name')

      echo "Updating $NAME ($ID) → 1m"

      UPDATED_BODY=$(echo "$ROW" | base64 --decode | jq '
      {
        type,
        name,
        enabled,
        schedule: {
          number: "1",
          unit: "m"
        },
        locations,
        timeout,
        max_attempts,
        wait,
        mode,
        ipv4,
        ipv6,
        host,
        retest_on_failure
      }')

      RESPONSE_UPDATE=$(curl -s -w "\n%{http_code}" -X PUT \
        "$KIBANA_URL/s/$SPACE/api/synthetics/monitors/$ID" \
        -H "kbn-xsrf: true" \
        -H "Authorization: ApiKey $API_KEY" \
        -H "Content-Type: application/json" \
        -d "$UPDATED_BODY")

      HTTP_BODY=$(echo "$RESPONSE_UPDATE" | head -n -1)
      HTTP_CODE=$(echo "$RESPONSE_UPDATE" | tail -n 1)

      if ["$HTTP_CODE" -ne 200]; then
        echo "❌ Failed to update $NAME ($ID)"
        echo "$HTTP_BODY"
      else
        echo "✅ Updated $NAME ($ID)"
      fi

      sleep 0.2
    fi

  done

  PAGE=$((PAGE + 1))

done

echo "Update complete."

```

**Script Execution :**

```auto
./fetch-synthetics-icmp.sh
e79d4471-6c87-4f87-9724-f7affe843250 | Non-Host-ICMP | 3m | space=default
64ddc109-1309-464d-b749-75176edd6723 | Google-ICMP | 3m | space=default
590c738d-364b-415c-ac68-bf440c42d0ae | Cloudfare-ICMP | 3m | space=default

./update-synthetics-icmp.sh
Updating ICMP monitors from 3m to 1m...
-----------------------------------------
Updating Cloudfare-ICMP (590c738d-364b-415c-ac68-bf440c42d0ae) → 1m
✅ Updated Cloudfare-ICMP (590c738d-364b-415c-ac68-bf440c42d0ae)
Updating Google-ICMP (64ddc109-1309-464d-b749-75176edd6723) → 1m
✅ Updated Google-ICMP (64ddc109-1309-464d-b749-75176edd6723)
Updating Non-Host-ICMP (e79d4471-6c87-4f87-9724-f7affe843250) → 1m
✅ Updated Non-Host-ICMP (e79d4471-6c87-4f87-9724-f7affe843250)
Update complete.

./fetch-synthetics-icmp.sh
#

Need to update the script to take filter as 1 instead of 3 : 

./fetch-synthetics-icmp.sh
e79d4471-6c87-4f87-9724-f7affe843250 | Non-Host-ICMP | 1m | space=default
64ddc109-1309-464d-b749-75176edd6723 | Google-ICMP | 1m | space=default
590c738d-364b-415c-ac68-bf440c42d0ae | Cloudfare-ICMP | 1m | space=default

```

This was tested in v9.3.1

Thanks!!

---

<div class="post-metadata">

**Author:** ![carly.richmond](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/carly.richmond/32/104935_2.png) [@carly.richmond](https://discuss.elastic.co/u/carly.richmond)\
**Post date:** [March 3, 2026, 11:57am UTC](https://discuss.elastic.co/t/how-to-bulk-update-synthesis-icmp-monitor-frequency/385291/5 "2026-03-03T11:57:42Z")

</div>

I would recommend using the specific synthetics API above rather than manipulating the indices itself. I'm not 100% sure that there are other operations taking place apart from updating the indices, but [looking at the edit handler](https://github.com/elastic/kibana/blob/f97e2af6ee3e7ff229ed53cac89dd0d345b74948/x-pack/solutions/observability/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts#L61) you would bypass some additional logic such as validation.

In terms of the get request to get all ICMP monitors, the HTTP request would be something like the below:

```auto
GET /api/synthetics/monitors?monitorTypes=icmp

```

Hope that helps!

---

<div class="post-metadata">

**Author:** ![Whoami1980](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whoami1980/32/147545_2.png) [@Whoami1980](https://discuss.elastic.co/u/Whoami1980)\
**Post date:** [March 4, 2026, 3:37am UTC](https://discuss.elastic.co/t/how-to-bulk-update-synthesis-icmp-monitor-frequency/385291/6 "2026-03-04T03:37:23Z")

</div>

@carly.richmond Thanks for the assistance.

Whats the difference between id and config\_id?

Can we run bash shell script in the dev tools? I dont think so. correct me if I am wrong.

Do u have an example of using the loop from get to update the values in devtools?

"Then you can loop through each one, using the id in a subsequent call to the Update monitors API, specifying the schedule value as 1."

Thanks

---

<div class="post-metadata">

**Author:** ![carly.richmond](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/carly.richmond/32/104935_2.png) [@carly.richmond](https://discuss.elastic.co/u/carly.richmond)\
**Post date:** [March 4, 2026, 9:29am UTC](https://discuss.elastic.co/t/how-to-bulk-update-synthesis-icmp-monitor-frequency/385291/7 "2026-03-04T09:29:44Z")

</div>

@Whoami1980 you can't run bash scripts in DevTools. But you should be able to run the script logic provided above by @Tortoise in a Linux-based environment just like normal scripts. DevTools is intended for adhoc running of commands and not full scripting.

My guess is that `id` refers to the unique ID of a single monitor, meanwhile `config_id` will be the unique reference for the configuration. For example you may have a Playwright-based configuration used in several monitors.

Hope that helps!
