If I replace prow_ref with other values ie surface, or remove AND tags ? 'prow_ref' completely it takes about 4 minutes to run. The returned data from that is about 2x to 4x the amount of the original query.
I have a few other sql/postpass routines, run within overpass turbo or a leaflet html, which download much more data, in seconds.
You haven’t asked for this advice and it is not the main reason for slowness. However, I still recommend to use regular expressions if they are really necessary only. Cases like this can be written as tags->>'highway' IN ('footway', 'steps', 'track', 'cycleway', 'bridleway', 'pedestrian', 'service', 'residential', 'unclassified') if you don’t intend to catch a highway=bridleway_simulation as well.
But back to your original question:
Database queries are slow if the query engine has to read all entries in the table (“full table scan”). Queries become reasonable performant if they can use an index. The database at postpass.geofabrik.de has a spatial index on the geom (type Geometry) column and an index on the keys of the tags column (type JSONB). If you cast geom to geography, your query cannot use the spatial index.
This means, the query optimizer uses the index on tags if the queries key (prow_ref) is no frequent OSM key. However, surface is very common.
If your spatial condition involves casting to geography you have to add a second condition without casting as a rough filter. In your case, you can add a ST_Expand(ST_SetSRID(ST_MakePoint(-2.35969,51.38138),4326), 0.005) && geom (distance to be adapted to your latitude). The distance should be larger than 500 meter. It only serves as a rough filter to skip most data.
tags ? 'prow_ref is the only part of that query that can use an index. Regular expressions can never use an index, and more generally tags->>'key' == 'value' can’t use the an index. Treat the ->> operator as being independent of what you do with the result of that operation.
The PostgreSQL docs go over what the GIN index covers but generally you want to use contains and overlap operators - equivalent to && if you were doing arrays.