# What are 'visibility tasks'?

**URL:** <https://community.temporal.io/t/what-are-visibility-tasks/5118>\
**Category:** Community Support\
**Tags:** advanced\_visibility, visibility\
**Created:** [June 27, 2022, 8:46pm UTC](https://community.temporal.io/t/what-are-visibility-tasks/5118 "2022-06-27T20:46:58Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![arpan](https://avatars.discourse-cdn.com/v4/letter/a/e480ec/32.png) [@arpan](https://community.temporal.io/u/arpan)\
**Post date:** [June 27, 2022, 8:46pm UTC](https://community.temporal.io/t/what-are-visibility-tasks/5118/1 "2022-06-27T20:46:58Z")

</div>

I’m trying to resolve an issue where read queries to the visibility\_tasks table (in temporal db) are failing because the queries would return too many rows. I’m trying to evaluate the impact of purging old rows from the table. I couldn’t find any information on the visibility\_tasks table in the docs or this forum. Any context would be appreciated.

---

<div class="post-metadata">

**Author:** ![alex](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/alex/32/15_2.png) [@alex](https://community.temporal.io/u/alex)\
**Post date:** [June 28, 2022, 8:14pm UTC](https://community.temporal.io/t/what-are-visibility-tasks/5118/3 "2022-06-28T20:14:13Z")

</div>

`visibility_task` is internal concept similar to `transfer_task` or `timer_task`. Basically they are used to update visibility store every time when new workflow starts, closes, or call `UpdateSearchAttributes` API. Also `visibility_task` is created when retention deletes workflow from main database and visibility store as well. These tasks are also short lived and if visibility task processor (which lives inside history service) works fine they shouldn’t be accumulated.

So I would have 2 questions here:

1. How do you end up with too many rows in `visibility_taks` table.
2. How do you know if those rows are old?

---

<div class="post-metadata">

**Author:** ![arpan](https://avatars.discourse-cdn.com/v4/letter/a/e480ec/32.png) [@arpan](https://community.temporal.io/u/arpan)\
**Post date:** [June 29, 2022, 7:17pm UTC](https://community.temporal.io/t/what-are-visibility-tasks/5118/4 "2022-06-29T19:17:26Z")

</div>

Hey Alex, this question was pretty bad, I completely misread an error trace.

The number of rows in the visibility\_tasks table or the age of the rows was never the issue.

These are the errors I was seeing in my history logs -  
`{"level":"error","ts":"2022-06-29T19:14:17.080Z","msg":"Operation failed with internal error.","service":"history","error":"GetVisibilityTasks operation failed. Select failed. Error: Error 10001: target: temporal.55-aa.primary: vttablet: rpc error: code = Aborted desc = Row count exceeded 15000 (errno 10001) (sqlstate HY000) (CallerID: temporal): Sql: \"select task_id, `data`, data_encoding from visibility_tasks where shard_id = :v1 and task_id > :v2 and task_id <= :v3 order by shard_id asc, task_id asc\", BindVars: {#maxLimit: \"type:INT64 value:\\\"15001\\\"\"v1: \"type:INT64 value:\\\"1145\\\"\"v2: \"type:INT64 value:\\\"870337237\\\"\"v3: \"type:INT64 value:\\\"931136076\\\"\"}","metric-scope":19,"shard-id":1145,"logging-call-at":"persistenceMetricClients.go:676","stacktrace":"go.temporal.io/server/common/log.(*zapLogger).Error\n\t/temporal/common/log/zap_logger.go:143\ngo.temporal.io/server/common/persistence.(*workflowExecutionPersistenceClient).updateErrorMetric\n\t/temporal/common/persistence/persistenceMetricClients.go:676\ngo.temporal.io/server/common/persistence.(*workflowExecutionPersistenceClient).GetVisibilityTasks\n\t/temporal/common/persistence/persistenceMetricClients.go:419\ngo.temporal.io/server/service/history.(*visibilityQueueProcessorImpl).readTasks\n\t/temporal/service/history/visibilityQueueProcessor.go:320\ngo.temporal.io/server/service/history.(*queueAckMgrImpl).readQueueTasks.func1\n\t/temporal/service/history/queueAckMgr.go:107\ngo.temporal.io/server/common/backoff.Retry\n\t/temporal/common/backoff/retry.go:103\ngo.temporal.io/server/service/history.(*queueAckMgrImpl).readQueueTasks\n\t/temporal/service/history/queueAckMgr.go:111\ngo.temporal.io/server/service/history.(*queueProcessorBase).processBatch\n\t/temporal/service/history/queueProcessor.go:263\ngo.temporal.io/server/service/history.(*queueProcessorBase).processorPump\n\t/temporal/service/history/queueProcessor.go:220"}`

It’s not the number of rows in the _table_ that’s an issue, it’s the number of rows in a query’s result.

It’s because our SQL db has a restriction that a response to a query can’t exceed 15k rows.

While I can request an exception to that cap, is there a way I can tweak some configs to get the history service to never pull more than a certain number of visibility\_tasks at once?

---

<div class="post-metadata">

**Author:** ![vimal\_dinakaran](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/vimal_dinakaran/32/3901_2.png) [@vimal\_dinakaran](https://community.temporal.io/u/vimal_dinakaran)\
**Post date:** [October 23, 2025, 3:58am UTC](https://community.temporal.io/t/what-are-visibility-tasks/5118/5 "2025-10-23T03:58:55Z")

</div>

Did you find way to fix this ? We are seeing high latency in  
delete from history\_scheduled\_tasks where shard\_id = \_ AND category\_id = \_ AND visibility\_timestamp \> \_ AND visibility\_timestamp \<= \_ . In some cases, it is causing lock contention.

Temporal version: 1.22

Is this fixed in latest release ?
