What are the pros and cons of PostGIS geography and geometry types?

Geography features are always stored in WGS84 prior to PostGIS 2.2; since then any lon/lat-based spatial reference system can be used. Measurements based on geography features will be in meters instead of CRS units and PostGIS will use geodetic calculations instead of planar geometry.

No all functions support geometry but you can cast between geometry and geography. For the current function list see: https://postgis.net/docs/PostGIS_Special_Functions_Index.html#PostGIS_GeographyFunctions

I don't think it's possible to recommend either geography or geometry for large databases. It depends on what you are doing with your data. As calculations on the sphere are more complicated, I'd expect analyses to be slower on geography features. You also have to transform all your data to WGS84 to use geography.

If you do a lot of measurements and e.g. have to compare sizes of large polygons, it would make sense to use geography rather than geometry.

I found the following useful: http://postgis.net/workshops/postgis-intro/geography.html

The topic is also covered in "PostGIS in Action" (ISBN: 9781935182269).


I use my intuitive "rules of thumb"... It is useful for a rapid decision,

  • About your DATABASE: if features and/or spatial analysis are of continental-scale, and need precision (serious applications) use geography. Else use geometry: when all database is about same (city-scale) region, or you not need precision, etc. you need only geometry.
    See similar rule at the suggest lecture of @underdark.

  • About your needs in terms of PERFORMANCE/PRECISION BALANCE: geometry is faster; if you need performance and think to use geography, do your benchmarks first.


Key-concepts

On this page, we see some key-words and the focus on some concepts: precision, performance, and something like flexibility/commodity of use.

As remembered by others, the difference, for store and calculations, is the use of sphere in geography and plane in geometry:

  • the sphere (geography) is better, more precise. See the Los Angeles/Paris example.
  • evolution of geography: as @DavidF say, "geography type was more recently added, so fewer functions are supported/implemented".

Perhaps on the year 2020 all GIS databases will be set to the same standard SRID/EPSG (equivalent to the nowadays 4326 code, for WGS84). Today geography is not a default choice because of performance and functional limitations.

Discussion

In my opinion it is a question of "best practices", not a deep technical/theoretical problem.

Precision

After estimate the error on your data, do your tests and compare results: the precision gains with geography are higher than error of data? The ST_Distance function (with MAX and AVG aggregators) is the main reference in this kind of experiment.

Performance

Examples of benchmarks in an urban area of ~100km2 (diameter ~11km), all stored as geometry, in a planar UTM coordinate system. NOTE: starting with the frequently used geometry/geography conversion — frequently because some functions not exist and some others, like ST_Buffer and ST_Intersection, do conversion internally.

Bench#1: a table with ~87000 polygons representing urban lots, each with poly with (avg) ~13 points,

 BEGIN; EXPLAIN ANALYSE CREATE TABLE temp_geom AS 
        SELECT gid, the_geom FROM urbanlots; ROLLBACK;
 -- time 2080 ms   ~ 2.0 s
 BEGIN; EXPLAIN ANALYSE CREATE TABLE temp_geog AS 
        SELECT gid, Geography(ST_Transform(the_geom,4326)) AS geog 
        FROM urbanlots; ROLLBACK;
 -- time 12374 ms ~ 12.4 s  ~ 6 * geometry.

so, geography_time=6*geometry_time.

Bench#2: a table with ~3500 polygons representing urban blocks, each with poly with (avg) ~50 points: 0.6s vs 2.7s, geography_time=4.5*geometry_time.

Bench#3: ~10000 lines representing urban streets, each with ~5 points. ~0.87s vs ~0.36s, geography_time=2.4*geometry_time.

Back to Bench#2, creating the tables and doing queries,

 EXPLAIN ANALYSE SELECT ST_Area(g.the_geom)+ST_Distance(g.the_geom,t.the_geom) 
         FROM temp_geom g, (SELECT the_geom FROM temp_geom WHERE gid=1) as t;
 -- time 182 ms   ~ 0.2 s
 EXPLAIN ANALYSE SELECT ST_Area(g.geog)+ST_Distance(g.geog,t.geog) 
         FROM temp_geog g, (SELECT geog FROM temp_geog WHERE gid=1) as t;
 -- time 58657 ms  ~ 59 s  ~  300*geometry
 -- curioselly for only distances, geography=4*geometry

Conclusion: for little tasks and good hardaware, the times converge to the "acceptable-same time", but for big tasks, there are performance ratings to consider.

Flexibility/Commodity

On the benchmarks I do a day-by-day task, checking the number of points (by ST_NPoints)... It is an example of operation that not exists for geography, needs cast. The "geography/geometry cast" is an annoying task for programmers, masters, etc.

When reusing libraries of SQL and PL/pgSQL functions, geography need adaptations. And, if you want to optimize code, or avoid precision problems with a lot of intermediary conversions, the absence of a complete set of build-in functions, with geography, is another problem. Program for geography, is not a easy task.

Process-only, data interchange, etc.

For non-usual demand, with no intensive user like Mapserver, when your only (PostGIS) work is to process input data and return at any time (like hours or days) the processed data, the rule of thumb is "use geography if you are comfortable!" (see "Flexibility/Commodity" above). If not, check usual rules.
NOTE: of course, if your (non-usual) task is only show data from PostGIS to Mapserver, with no process need, to preserve the same (geometry or geography) of your input data, is better decision.

I believe the data centralization is another task where geography is better: in context where the diversity of input formats and reference systems are usual, the use of a standard, such as that enforced by the geography, is beneficial... Convention over configuration is a good principle when centralization and data interchange are the business focus (see Google Maps!).


I believe that the most significant difference is that with the geography type, calculations are made on a sphere representing the earth as opposed to the flat surface used in calculations made on geometry type features.

The docs are pretty good: http://postgis.net/docs/manual-1.5/ch04.html#PostGIS_Geography

The geography type was more recently added, so fewer functions are supported/implemented.